My dialogue system shows the wrong the wrong dialogue for the wrong NPC

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? I want to achieve so that the dialogue system doesn’t bug out and show the wrong dialogue for the wrong NPC.

  2. What is the issue? My dialogue system sometimes bugs out and shows the wrong dialogue for the wrong npc.

  3. What solutions have you tried so far? I have remade the dialogue system three times, this is the third remake. This issue still persisted within the older systems.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

local DialogueModule = {
	["WaitTime"] = 2.25,
	["DialogueTypeSpeed"] = 0.15,
	["PlayerIcons"] = {
		["Option1Button"] = "rbxassetid://136389297156187", -- Neutral
		["Option2Button"] = "rbxassetid://138394273033357", -- Worried
		["Option3Button"] = "rbxassetid://135397907689374" -- Sad
	},
	["PlayerName"] = "M"
}

DialogueModule.__index = DialogueModule

function DialogueModule.Setup(npcData)
	local newNpcData = setmetatable(npcData or {}, DialogueModule)
	newNpcData.Name = newNpcData.Name or "DialogueError"
	newNpcData.Dialogues = newNpcData.Dialogues or nil
	newNpcData.Icons = newNpcData.Icons or nil
	newNpcData.DialogueGUI = newNpcData.DialogueGUI or nil
	newNpcData.HasResponses = newNpcData.HasResponses or nil
	
	return newNpcData
end

function DialogueModule:DialogueStart(iconName, char)
	local DialogueBox = self.DialogueGUI.DialogueBox
	
	DialogueBox.Visible = true
	DialogueBox.ProfileFrame.IconLabel.Image = self.Icons[iconName]
	DialogueBox.NameFrame.NameText.Text = self.Name
	DialogueBox.DialogueText.Text = self.Dialogues.DialogueBegin
	char:WaitForChild("HumanoidRootPart").Anchored = true
	for i = 0, #DialogueBox.DialogueText.Text do
		task.wait(DialogueModule.DialogueTypeSpeed)
		DialogueBox.DialogueText.MaxVisibleGraphemes = i
	end
	task.wait(DialogueModule.WaitTime)
	if self.HasResponses then
		print("The NPC has responses!")
		DialogueModule:ResponseStart(DialogueBox, self, char)
	else
		print("Dialogue ended.")
		char:WaitForChild("HumanoidRootPart").Anchored = false
		DialogueBox.Visible = false
	end
end

function DialogueModule:ResponseStart(DialogueBox, NPCData, Char)
	local connection
	for i, v in pairs(DialogueBox.Options:GetChildren()) do
		v.Visible = true
		v.Text = NPCData.Dialogues[v.Name].ButtonText
		connection = v.MouseButton1Click:Connect(function()
			connection:Disconnect()
			for i, p in pairs(DialogueBox.Options:GetChildren()) do
				p.Visible = false
			end
			DialogueBox.DialogueText.Text = NPCData.Dialogues[v.Name].PlayerResponse
			DialogueBox.ProfileFrame.IconLabel.Image = DialogueModule.PlayerIcons[v.Name]
			DialogueBox.NameFrame.NameText.Text = DialogueModule.PlayerName
			for i = 0, #DialogueBox.DialogueText.Text do
				task.wait(DialogueModule.DialogueTypeSpeed)
				DialogueBox.DialogueText.MaxVisibleGraphemes = i
			end
			task.wait(DialogueModule.WaitTime)
			DialogueBox.DialogueText.Text = NPCData.Dialogues[v.Name].DialogueEnd
			DialogueBox.ProfileFrame.IconLabel.Image = NPCData.Icons[v.Name]
			DialogueBox.NameFrame.NameText.Text = NPCData.Name
			for i = 0, #DialogueBox.DialogueText.Text do
				task.wait(DialogueModule.DialogueTypeSpeed)
				DialogueBox.DialogueText.MaxVisibleGraphemes = i
			end
			task.wait(DialogueModule.WaitTime)
			DialogueBox.Visible = false
			Char:WaitForChild("HumanoidRootPart").Anchored = false -- Just to make sure that the player will not remain stuck.
		end)
	end
end

return DialogueModule

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

Side note: The dialogues are stored within a table, called as “NpcData”.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Player = game:GetService("Players").LocalPlayer

local DialogueModule = require(ReplicatedStorage.Modules.DialogueModule)

local prompt = script.Parent
local NPCData = {
	["Name"] = "NPC2",
	["HasResponses"] = true,
	["Dialogues"] = {
		["DialogueBegin"] = "Hello, this is a test for the rewritten dialogue system! (DialogueBegin NPC2)",
		["Option1Button"] = {
			["PlayerResponse"] = "Why yes, it is! (Player response1 NPC2)",
			["DialogueEnd"] = "This is the end of the dialogue! (DialogueEnd1 NPC2)",
			["ButtonText"] = "Test12"
		},
		["Option2Button"] = {
			["PlayerResponse"] = "This is the second response2 for NPC2!",
			["DialogueEnd"] = "Yup, of course!",
			["ButtonText"] = "Test22"
		},
		["Option3Button"] = {
			["PlayerResponse"] = "The third response3 for NPC2!",
			["DialogueEnd"] = "Yeah, sure is!",
			["ButtonText"] = "Test32"
		}
	},
	["Icons"] = {
		["DialogueBegin"] = "rbxassetid://134101905955418",
		["Option1Button"] = "rbxassetid://123519335021234", -- Happy
		["Option2Button"] = "rbxassetid://78505786846892", -- Worried
		["Option3Button"] = "rbxassetid://135811693051820" -- Sad
	},
	["DialogueGUI"] = Player.PlayerGui:WaitForChild("DialogueGUI")
}

prompt.Triggered:Connect(function()
	local char = Player.Character or Player.CharacterAdded:Wait()
	local NPCDialogue = DialogueModule.Setup(NPCData)
	task.wait()
	NPCDialogue:DialogueStart("DialogueBegin", char)
end)

1 Like

The issue is how you are handling the connections. Even though you are trying to set it up in a loop, only your final MouseButton1Click is actually assigned to the connection variable.

I would recommend you use an array, which would contain all connections.

e.g.:

	local connections = {}
	for i, v in pairs(DialogueBox.Options:GetChildren()) do
		v.Visible = true
		v.Text = NPCData.Dialogues[v.Name].ButtonText
		table.insert(connections, v.MouseButton1Click:Connect(function()
			for _, connection in connections do			
				connection:Disconnect()
			end
		....
	-- add an extra bracket to the end of the MouseButton1Click handler
1 Like


I have a difficulty on following instructions, am I doing it right?

1 Like

I don’t know, at all.

I seriously don’t.

Not quite right.
Here’s the change done within the function.

function DialogueModule:ResponseStart(DialogueBox, NPCData, Char)
	local connections = {}
	for i, v in pairs(DialogueBox.Options:GetChildren()) do
		v.Visible = true
		v.Text = NPCData.Dialogues[v.Name].ButtonText
		table.insert(connections, v.MouseButton1Click:Connect(function()
			for _, connection in connections do
				connection:Disconnect()
			end

			for i, p in pairs(DialogueBox.Options:GetChildren()) do
				p.Visible = false
			end
			DialogueBox.DialogueText.Text = NPCData.Dialogues[v.Name].PlayerResponse
			DialogueBox.ProfileFrame.IconLabel.Image = DialogueModule.PlayerIcons[v.Name]
			DialogueBox.NameFrame.NameText.Text = DialogueModule.PlayerName
			for i = 0, #DialogueBox.DialogueText.Text do
				task.wait(DialogueModule.DialogueTypeSpeed)
				DialogueBox.DialogueText.MaxVisibleGraphemes = i
			end
			task.wait(DialogueModule.WaitTime)
			DialogueBox.DialogueText.Text = NPCData.Dialogues[v.Name].DialogueEnd
			DialogueBox.ProfileFrame.IconLabel.Image = NPCData.Icons[v.Name]
			DialogueBox.NameFrame.NameText.Text = NPCData.Name
			for i = 0, #DialogueBox.DialogueText.Text do
				task.wait(DialogueModule.DialogueTypeSpeed)
				DialogueBox.DialogueText.MaxVisibleGraphemes = i
			end
			task.wait(DialogueModule.WaitTime)
			DialogueBox.Visible = false
			Char:WaitForChild("HumanoidRootPart").Anchored = false -- Just to make sure that the player will not remain stuck.
		end))
	end
end
1 Like

Thank you, I’ll do a test on it to see if it works!

It works flawlessly, thank you so much!

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