Hello Roblox Support / Developers,
I am experiencing a very unusual and persistent issue with the DialogChoiceSelected
event on a Dialog
object in my game, even after extensive debugging. The core problem is that the DialogChoiceSelected
event does not appear to fire or register on the server-side script when a player makes a choice, despite the dialogue UI updating visually on the client.
Problem Description:
- I have a
Dialog
object set up on an NPC’sHead
(e.g.,Workspace.NoobNPC.Head.Dialog
). - The
Dialog.InitialPrompt
and initialDialogChoice
(e.g., “Am I dreaming?”) are correctly displayed to the player. - When a player clicks the initial
DialogChoice
(“Am I dreaming?”), the following happens:
- Visually (Client-Side): The NPC’s dialogue prompt correctly changes to the
ResponseText
of the clickedDialogChoice
(e.g.,...
ifResponseText
is set to...
on theDialogChoice
). - Script-wise (Server-Side): No prints from the
DialogChoiceSelected
event connection are displayed in the Output window. The script’sDialogChoiceSelected:Connect()
function does not appear to execute at all.
What I’m trying to achieve: I want the server script to detect which DialogChoice
the player selected so it can update the dialogue options and NPC’s prompt dynamically, and eventually trigger game logic (like a teleport).
Environment Details:
- Game Type: Roblox experience (testing in Play Solo).
- Roblox Studio Version: [Specify your current Roblox Studio version, e.g., latest public version as of June 30, 2025]
- Operating System: [e.g., Windows 10, macOS Sonoma]
Steps to Reproduce:
- Create a
Baseplate
project. - Set up the following hierarchy and properties:
Workspace
:Part
namedHouseSpawnPoint
(Anchored=true, CanCollide=false, Transparency=1)Model
namedNoobNPC
(Anchored=true)Humanoid
(child ofNoobNPC
)Part
namedHead
(child ofNoobNPC
, Anchored=true)Dialog
(child ofHead
)InitialPrompt
: “Hello there…”InUse
:true
(checked)ActionDistance
:100000
(for easy testing)DialogChoice
(child ofDialog
)Name
:AmIDreaming
Title
:Am I dreaming?
ResponseText
:...
(optional, but shows the client-side change)
ReplicatedStorage
:RemoteEvent
namedWakeTeleport
- Place the following script in
ServerScriptService
(namedDetectWakeUpChoice
):`
-- Script: DetectWakeUpChoice
-- Location: ServerScriptService
-- Purpose: Manages the NoobNPC's dialogue flow, teleports the player, and triggers client effects.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- RemoteEvent for client-side effects (ensure it exists in ReplicatedStorage)
local remote = ReplicatedStorage:WaitForChild("WakeTeleport")
print("[DEBUG SERVER] RemoteEvent 'WakeTeleport' found.")
-- Get the NoobNPC and its Dialog object
local noob = workspace:WaitForChild("NoobNPC")
print("[DEBUG SERVER] NoobNPC found in workspace.")
-- Recursive search for Dialog (e.g., in Workspace.NoobNPC.Head.Dialog)
local dialog = noob:FindFirstChild("Dialog", true)
if not dialog then
warn("[SERVER ERROR] Could not find Dialog in NoobNPC or its children! Please ensure it's Workspace.NoobNPC.Head.Dialog")
return
end
print("[DEBUG SERVER] Dialog object found:", dialog:GetFullName())
-- Get the CFrame of your designated teleport spot (ensure HouseSpawnPoint Part exists in Workspace)
local HOUSE_SPAWN_CFRAME = nil
local success, errorMessage = pcall(function()
HOUSE_SPAWN_CFRAME = workspace:WaitForChild("HouseSpawnPoint").CFrame
end)
if not success then
warn("[SERVER ERROR] Could not find 'HouseSpawnPoint' in Workspace! Teleportation will fail. Error: " .. errorMessage)
return
else
print("[DEBUG SERVER] HouseSpawnPoint CFrame acquired.")
end
-- Optional: If you want to use a ClickDetector to activate the dialogue
-- This section is temporary debug to help activate the dialogue if default isn't working.
local clickDetectorParent = noob:FindFirstChild("HumanoidRootPart", true)
if not clickDetectorParent then
clickDetectorParent = noob:FindFirstChild("Head", true)
end
if clickDetectorParent then
local foundClickDetector = clickDetectorParent:FindFirstChildOfClass("ClickDetector")
if not foundClickDetector then -- Only add if one doesn't exist
foundClickDetector = Instance.new("ClickDetector")
foundClickDetector.MaxActivationDistance = 50 -- Set a range
foundClickDetector.Parent = clickDetectorParent
print("[DEBUG SERVER] Added temporary ClickDetector to NoobNPC.")
end
-- Connect to the found/created ClickDetector
foundClickDetector.MouseClick:Connect(function(playerClicked)
print("[DEBUG SERVER] ClickDetector detected click by " .. playerClicked.Name)
if not dialog.InUse then
dialog.InUse = true
print("[DEBUG SERVER] Force-set Dialog.InUse to true via ClickDetector.")
end
end)
else
warn("[DEBUG SERVER] HumanoidRootPart or Head not found for NoobNPC. ClickDetector setup skipped.")
end
-- END OPTIONAL CLICKDETECTOR SETUP
-- Function to update the Dialog's prompt and its choices
-- This function is crucial for changing the dialogue options.
local function updateDialogChoices(newInitialPrompt, newChoicesTable)
print("[DEBUG SERVER] Entering updateDialogChoices function.")
print(" New InitialPrompt (desired):", newInitialPrompt)
-- Attempt to update the main prompt
local success, err = pcall(function()
dialog.InitialPrompt = newInitialPrompt
end)
if success then
print(" Dialog InitialPrompt updated successfully.")
else
warn("[ERROR SERVER] Failed to update Dialog InitialPrompt: " .. err)
return -- Exit if this critical step fails
end
-- Clear existing choices
print(" Attempting to clear existing DialogChoices...")
local childrenToDestroy = {}
for _, child in ipairs(dialog:GetChildren()) do
if child:IsA("DialogChoice") then
table.insert(childrenToDestroy, child)
end
end
if #childrenToDestroy > 0 then
for _, oldChoice in ipairs(childrenToDestroy) do
local destroySuccess, destroyErr = pcall(function()
oldChoice:Destroy()
end)
if destroySuccess then
print(" Successfully destroyed old choice:", oldChoice.Name)
else
warn("[ERROR SERVER] Failed to destroy old choice " .. oldChoice.Name .. ": " .. destroyErr)
end
end
print(" Finished attempting to clear old DialogChoices.")
else
print(" No DialogChoices found to clear, or none were DialogChoices.")
end
-- Add new choices based on the table provided
print(" Attempting to add new DialogChoices...")
if #newChoicesTable > 0 then
for i, choiceData in ipairs(newChoicesTable) do
local addSuccess, addErr = pcall(function()
local newChoice = Instance.new("DialogChoice")
newChoice.Name = choiceData.Name
newChoice.Title = choiceData.Title
newChoice.ResponseText = choiceData.ResponseText
newChoice.UserDialog = choiceData.UserDialog
newChoice.Parent = dialog
print(" Successfully added new choice:", newChoice.Name, "with title:", newChoice.Title)
end)
if not addSuccess then
warn("[ERROR SERVER] Failed to add new choice #" .. i .. " (Name: " .. (choiceData.Name or "N/A") .. "): " .. addErr)
end
end
print(" Finished attempting to add new DialogChoices.")
else
print(" No new choices provided in newChoicesTable. (Table was empty)")
end
print("[DEBUG SERVER] Exiting updateDialogChoices function.")
end
-- Connect to the DialogChoiceSelected event to handle player responses
dialog.DialogChoiceSelected:Connect(function(player, chosenDialogChoice)
print("\n[DEBUG SERVER] DialogChoiceSelected event fired!")
print(" Player:", player.Name)
print(" Chosen DialogChoice Name:", chosenDialogChoice.Name)
if chosenDialogChoice.Name == "AmIDreaming" then
-- Player selected "Am I dreaming?"
print("[DEBUG SERVER] Processing 'AmIDreaming' choice.")
-- Noob responds "I am your dream..." and offers "Huh?" as the next choice
updateDialogChoices(
"I am your dream...", -- Noob's response
{
{
Name = "Huh", -- Crucial name for the next choice
Title = "Huh?", -- What the player sees as a clickable option
ResponseText = "Precisely. The moment of truth has arrived.", -- Noob's response to "Huh?" (though the prompt changes immediately after)
UserDialog = "Huh?" -- What the player says
}
}
)
elseif chosenDialogChoice.Name == "Huh" then
-- Player selected "Huh?"
print("[DEBUG SERVER] Processing 'Huh' choice. Preparing for WAKE UP!")
-- Noob responds "WAKE UP!" and no more choices are offered
updateDialogChoices(
"WAKE UP!", -- The final, triggering prompt from Noob
{} -- No more choices after "WAKE UP!", as the sequence begins
)
-- Give a tiny moment for the dialogue to visually update on the client
task.wait(0.2)
print("[DEBUG SERVER] Short wait after 'WAKE UP!' prompt update.")
-- --- Trigger the Teleport and Client Effects ---
local character = player.Character
if not character then
warn("[SERVER ERROR] Character not found for player " .. player.Name .. ". Cannot teleport.")
return
end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then
warn("[SERVER ERROR] HumanoidRootPart not found for character " .. character.Name .. ". Cannot teleport.")
return
end
if HOUSE_SPAWN_CFRAME then
humanoidRootPart.CFrame = HOUSE_SPAWN_CFRAME
print("[DEBUG SERVER] Teleported " .. player.Name .. " to new house location.")
else
warn("[SERVER ERROR] HOUSE_SPAWN_CFRAME was nil. Teleportation skipped.")
end
remote:FireClient(player) -- Tell the client to start screen effects and new dialogue
print("[DEBUG SERVER] Fired 'WakeTeleport' RemoteEvent to client.")
-- Optionally, hide the Noob's dialogue after the sequence starts
dialog.InUse = false
print("[DEBUG SERVER] Noob's dialogue set to InUse = false.")
-- Or even destroy the NoobNPC if they are no longer needed
-- noob:Destroy()
else
print("[DEBUG SERVER] Unrecognized DialogChoice selected: ", chosenDialogChoice.Name)
end
end)
print("[DEBUG SERVER] DetectWakeUpChoice script running and DialogChoiceSelected event connected. Waiting for interaction.")
– (The one with all the DEBUG SERVER prints)5. Run the game using "Play" or "Play Solo." 6. Open the Output window. 7. Click on the
NoobNPC`.
8. Click the “Am I dreaming?” dialogue option.
Expected Behavior: Upon clicking “Am I dreaming?”, the Output window should display debug messages from the server script, specifically:
[DEBUG SERVER] DialogChoiceSelected event fired!
[DEBUG SERVER] Player: [YourPlayerName]
[DEBUG SERVER] Chosen DialogChoice Name: AmIDreaming
- Followed by prints from
updateDialogChoices
.
Actual Behavior: The NPC’s visual prompt changes to “…” (from DialogChoice.ResponseText
), but no new lines are printed in the Output window after the initial script load messages. This indicates the DialogChoiceSelected
event is not being processed by the server script.
Troubleshooting Steps Already Taken:
- Confirmed
DialogChoiceSelected
is connected to theDialog
object, notDialogChoice
. - Verified
Dialog.InUse
istrue
andActionDistance
is sufficient. - Verified NPC
Humanoid
presence. - Added extensive debug prints throughout the server script, especially within the
DialogChoiceSelected
connection andupdateDialogChoices
function; these prints do not fire. - Checked
Dialog.InstanceId
on both client (via F9 console) and server (via script prints); IDs match, confirming the script is listening to the correct object. - Performed a complete restart/reinstall of Studio and re-creation of all objects/scripts from a fresh baseplate.
- Tested on multiple fresh baseplates.
This bug is preventing the implementation of basic dialogue branching. Any insights or assistance would be greatly appreciated.
Thank you.