return {
['Hardware Guy'] = {
'Hello! Welcome to my hardware store. You can find a variety different items to customise your house with, including floor designs, wallpapers and paint!',
'Is there anything here that interests you?'
{
'Yes there is!' = true,
'No there is not!' = false,
}
}
}
I’m not exactly sure how to go about separating each section of the dialogue into specific sections. As the first piece of dialogue he says would need to return say a variable like ‘Question’ and have it set to false, so then my UI can show the ‘Press E to continue’, but then if the dialogue is a question, have my UI show the choice boxes. And then be able to have a response for either answer the player gives. I have already made all my UI, just not sure
Bare in mind, I’ve never looked into the Dialogue Editor, but heard mixed reviews on it, so not sure if I wanna head down that path, or just simply create my own. As well as I want my own UI for this, so not sure how to go about using the editor with my own UI. Makes more sense to just hard code it myself
From what I understand you want to categorise them by question or answer.
If that is what you want I’d do it like this.
return {
["Hardware Guy"] = {
Introduction = "Hello! Welcome to my hardware store. You can find a variety different items to customise your house with, including floor designs, wallpapers and paint!",
Questions = {"Is there anything here that interests you?"},
Answers = {"Yes there is!", "No there is not!"}
}
}
Introduction is just how he introduces himself, Questions is the questions he will ask, and Answers would be the answers that you can give
If a question can have multiple answers, I’d suggest grouping the answers in a table
Something similar to this nature so you can switch your ui based on Type. However, that may not be the approach you’re looking for, that’s just how I’d do it.
so it knows what index to jump to, and if the index is out of bounds then you know to exit, or just have it jump to the last index if you intend to add a “Farewell” message.
I feel like all of these maps and tables are over complicating what you want to be a logically sound system. I suggest using a tree. If you’re wondering what in the world leaves and a trunk have to do with programming, read up here. I’ll just explain in code
--Don't be fooled by the name! The variable is initialized and you would think its the whole tree but in reality we just want this to store the head node i.e. the conversation starter
local AnswerTree = {
Dialogues = {"Hey!", "Wanna buy something?"}, --An array of dialogues, because you brought up the concept of multiple messages before a prompt
Prompts = {"Yes please", "No thanks"} --should only be 0-2 of these
}
local onBuyYes = {Dialogues = {"Ok first let me ask how is your day going"},
Prompts = {"Great thanks for asking", "Not too nicely"}}
AnswerTree.Node1 = onBuyYes --gonna use 1 and 2 instead of 0 and 1 because of how lua indicies work
local onBuyNo = {Dialogues = {"Stop wasting my time and get moving"}} --this is a conversation endpoint, i.e. no prompts
AnswerTree.Node2 = onBuyNo
See how it works? You can easily traverse this tree by seeing the index of the response, and then indexing the tree by currentLevel["Node"..index] where current level is your current data set (will start off as answer tree) and index is the index of the response out of the prompts that were given. Using a tree will help you create a smooth dialogue script that won’t be a formidable mess in code. If you have troubles with trees or organizing let me know.
Unable to really test this as I’m about to head to bed, but I’m unsure of how exactly this actually works? Seems incredibly confusing.
local AnswerTree = {
Dialogues = {"Hey!", "Wanna buy something?"},
Prompts = {"Yes please", "No thanks"}
}
How can you tell from Dialogues, which need to prompts and which don’t? ‘Hey!’ wouldn’t require a prompt, but the question would. And I’m guessing the onBuyYes and onBuyNo are in response to whatever option the player has chosen?
Ideally you will only want to prompt the user after all the dialogues in that particular step have been run through, right? And yes, the two nodes are meant to act as “children” of the head node so you can recursively continue a dialogue as long as you want. Example of how you would employ this concept:
local currentStep = AnswerTree --default; where you want to start
while currentStep.Prompts do --keep the conversation going as long as there's prompts to keep it going
runThroughDialogues(currentStep.Dialogues) --have all the messages of that step run through
for promptIndex, text in pairs(currentStep.Prompts) do
local button = addPromptButton(text) --make a button to select this prompt
local currentIndex = promptIndex --promptIndex is a changing variable; make a local one for this specific button
local conn
conn = button.MouseButton1Click:Connect()
conn:Disconnect()
currentStep = currentStep["Node"..currentIndex] --move on to the next step we selected
end)
end
end
That’s why I went through all the trouble of adding nodes and whatnot, it might confuse you setting it up but in function all it is is a loop.
Keep in mind, that first node I put is not the entire dialogue. It is merely a step, and it happens to be the first.
This would probably be a fairly simple if not explicit implementation, I would suggest looking into those pick your ending goosebump books or something similar. Each entry is a page, some with a choice that makes you jump to a new spot, some you just continue sequentially to the next page.
If you want more dynamic dialogue to fit the context of the situation, you could do dialogue like how I did in an [attempted ] RPG that I made awhile ago.
Basically, I had a table with every interaction in it, and every entry would have a function that does its own logic.
["Dummy"] = function(player) --here, you could give the function any arguments you want, like the player name, player data, etc.
local answer = chat:Say(
"Speaker",
"[y/n]This is a yes/no question. Would you like to answer " .. player.Name .. "?"
)
--i made a custom dialogue thing which parsed the text for
--"[y/n]", which would then prompt the player with options and yield until the player responded
if answer then --basic logic
chat:Say("Speaker","you said yes")
else
chat:Say("Speaker","you said no")
end
end
Of course, this is a very simple snippet. This could be used to interact with the world, like opening doors, initiating cutscenes, etc.
For more flair, you could implement one of those markdown text modules that people have released to add color to your dialogue. (like this RichText module by Defaultio)
I’m fairly sure that I implemented a feature to have more custom options than “Yes” or “No”, but I cannot find examples of those because I haven’t worked on this project in awhile.
The Roblox Dialogue Editor handles this perfectly. It is currently broken and unmaintained though, so you’ll have to use a version that someone is actively updating and maintaining or one that has fixed applied.
return {
['Hardware Sam'] = {
[1] = {Msg = 'Hello! Welcome to my hardware store. You can find a variety different items to customise your house with, including floor designs, wallpapers and paint!', Type = 'Dialogue'},
[2] = {Msg = 'Is there anything here that interests you?', Type = 'Question', Responses = { ['Yes'] = 3, ['No'] = 4}},
[3] = {Msg = 'Take a look!', Type = 'Dialogue'},
[4] = {Msg = 'Farewell', Type = 'Dialogue'}
}
}
and this is how I iterate through the text
for i, v in pairs(DialogueData[NPC]) do
for iter = 1, #v.Msg do
Desc.Text = string.sub(v.Msg, 1, iter)
wait()
end
if v.Type == 'Dialogue' then
Action.Visible = true
else
QuestionAsked = true
Action.Visible = false
Choice1.Visible = true
Choice2.Visible = true
Choice1.Activated:Connect(function()
Continue = true
QuestionAsked = false
end)
Choice2.Activated:Connect(function()
Continue = true
QuestionAsked = false
end)
end
TextFinished = true
repeat wait() until Continue
Action.Visible = false
Continue = false
TextFinished = false
end
How can I then include the choice buttons to make choices?
Currently, picking clicking either one will make the text say
‘Farewell’
and then
‘Take a look!’
So not sure why it’s showing Farewell before Take a look considering farewell is the last thing in the table
Instead of iterating through the table, you should only need to reference the first item.
table[1] – starting point
if its a dialogue you continue to the next item,
table[2]
if its a question, the choice picks the next spot
answer = no
table[4]
-- start talking
inConvo = true
nextSpeech = 1
while inConvo do
v = DialogueDate[NPC][nextSpeech]
for iter = 1, #v.Msg do
Desc.Text = string.sub(v.Msg, 1, iter)
wait()
end
if v.Type == 'Dialogue' then
Action.Visible = true
nextSpeech = nextSpeech + 1
elseif v.Type == 'Farewell' then
inConvo = false
else
QuestionAsked = true
Action.Visible = false
Choice1.Visible = true
Choice2.Visible = true
Choice1.Activated:Connect(function()
Continue = true
QuestionAsked = false
nextSpeech = v.Responses.Yes
end)
Choice2.Activated:Connect(function()
Continue = true
QuestionAsked = false
nextSpeech = v.Responses.No
end)
end
repeat wait() until Continue
Action.Visible = false
Continue = false
end
Something like that. After the first item, the next one is decided by type of speech and the player interaction.
with the current set up though, you can only do yes/no questions
Don’t know what was causing your double response though
Seems to work well enough, however, is there a reason why if I choose yes, it still shows the farewell message?? Is there a way to just have it show the next message? And is there ways to incorporate a functions or something into this? As I want UI to appear, camera manipulation, etc. to occur when certain choices are picked
Did you leave a Take a look in your code elsewhere? It really doesn’t make sense with what you’ve shown here.
That or could your buttons be getting triggered when they shouldn’t?
I’m trying to have the function inside the dialogue data tho
return {
['Hardware Sam'] = {
[1] = {Msg = 'Hello! Welcome to my hardware store. You can find a variety different items to customise your house with, including floor designs, wallpapers and paint!', Type = 'Dialogue'},
[2] = {Msg = 'Is there anything here that interests you?', Type = 'Question', Responses = {['Yes'] = 3, ['No'] = 4}},
[3] = function()
print(1)
end,
[4] = {Msg = 'Goodbye', Type = 'Farewell'}
},
}