How can I integrate multiple-choice dialog into my existing dialog system?

I currently have a system that allows you to set an NPC’s dialog using a function. Like, for example:

NpcModule.setDialogText("An example message","An example character") -- There's other arguments but these are the only required

I want to make a multiple choice path possible through the system, but I’m having trouble with how I should go about making it.

I’ve been trying to wrap my head around this and this is the best I could come up with:

local resp1 = NpcModule.setDialogText("How are you?","An example character") -- Returns a string with the response selected by the player

if resp1=="good" then
    print("i'm good")
elseif resp1=="bad" then
    print("i'm bad")
end

The only drawback would from this system would be that this would create an if statement hell as soon as you have more than 2 nested multiple choices.

This is my first time making something like this, so I’d love to know any of you guys’ opinion or advice on this, especially of those who’ve already gone through something like this. Thanks!!!

In this case, I believe you could use an option table to handle responses. Basically, there is a table for the dialog responses, with information corresponding to each response. When the response is called, there can be a function within the table that is called based on the response.

Here’s a basic overview of this in code:

local responses = {
    {
        name = "good",
        -- any other possible attributes
        chosen = function(player){
            print(player.Name,"is good")
        }
    },
    {
        name = "bad"
        
        chosen = function(player){
            print(player.Name,"is bad")
        }
    }
}

-- ask question with response table options, save the response data that gets selected
local chosenResponseData = askQuestion()

-- call the chosen function on the chosen response, with player argument (optional) for relativity
chosenResponseData.chosen(playerWhoAsked)

Overall, this method is a lot more organized and customizable than using if-else statements. Hope this helps!

How would this work when nesting multiple choice dialogs?

For example, let’s say I’d want a structure like this (with dummy text generated by ai):

START
|
|-- Hello! How can I help you? (Player chooses a response)
    |
    |-- "Who are you?" 
    |      |-- "I'm a local guide. Nice to meet you!" 
    |      |      |-- "Nice to meet you too!" --> END
    |      |      |-- "I have more questions." --> Back to START
    |
    |-- "Where am I?" 
    |      |-- "You're in Rivertown, a small village by the river."
    |      |      |-- "What can I do here?" 
    |      |      |      |-- "You can explore the market, visit the docks, or hike in the hills!"
    |      |      |           |-- "Thanks!" --> END
    |      |      |           |-- "Tell me more about the market." --> (Additional branches)
    |
    |-- "Goodbye." --> END

I’m mostly looking for something that would work well in scenarios like this.

In that case, you can just nest the sub-responses into the response datas. Since sub-responses correspond to the previous response, the script can proceed to go into the next-nested response after one is picked. This creates an overall tree pattern where the tree can easily be viewed in the form of a table. You can add further things to response data that your script can process (eg end dialog, return to start), but I’ll leave that up to you.

This is how it would look like with nested responses. Keep in mind that this can be repeated infinitely.

local responses = {
    {
        name = "good",
        -- any other possible attributes
        chosen = function(player){
            print(player.Name,"is good")
        },

        subMessage = "are you sure about that",
        subResponses = {
            {
                name = "yes",
                chosen = function(player){
                    print(player.Name,"said yes")
                }
            },
            {
                name = "no",
                chosen = function(player){
                    print(player.Name,"said no")
                }
            },
        }
    },
    {
        name = "bad"
        
        chosen = function(player){
            print(player.Name,"is bad")
        }
    }
}

Doesn’t this reintroduce the problem I had with my if statement idea? Like, wouldn’t this also become an indentation hell after 2-3 subresponses?

I guess the way you’re using the tables looks a bit cleaner but I feel like it’ll still look messy once I put it into practice.