Chat message appearing twice (LegacyChatService)

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

  1. What do you want to achieve? Keep it simple and clear!
    Hello developers! So I’m currently designing a game where there is one player and two player plus play, and when the player selects 1P it sends them to a reserved server and sends a chat message saying “1P has turned has been turned on! Have fun.”
  2. What is the issue? Include screenshots / videos if possible!
    The message appears twice in the chat box.
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried applying debounces to the remote-event being fired, but nothing seems to work.

Module (in ServerScriptService)

game.Players.PlayerAdded:Connect(function(Player)
	local JoinData = Player:GetJoinData()
	if JoinData then
		local TeleportData = JoinData.TeleportData
		if TeleportData then
			minimumPlayers = TeleportData.minimumPlayers -- changes the minimum players to 1.
			SinglePlayerAysnc:FireClient(Player, "[S] Single player has been turned on. Have fun!", Color3.fromRGB(111, 204, 255))
		end
	end
end)

Local Script (in StarterPlayerScripts)

-- single player messages.
SinglePlayerAysnc.OnClientEvent:Connect(function(text, color)
	local success, errormessage = pcall(function()
		StarterGui:SetCore("ChatMakeSystemMessage", {Text = text, Color = color})
	end)
	
	if success then
		return success
	else
		warn(errormessage)
	end
end)
1 Like

Could you add a print on the line before FireClient and one at the start of OnClientEvent. Name them smtn like A and B, tell me how many times they each print.

2 Likes

Ok I have one solution that’s gonna sound Stupid,
It looks you have the localscript cloned twice somewhere.
CTRL+SHIFT+F “SinglePlayerAysnc”

3 Likes

They each print out once time, and also, I checked for duplicates of the script, but there are none.

Oh damn, could you send both scripts fully so I can check them?

1 Like

Ok so here are all the scripts:

The textbutton handler (local script)

local SoundService = game:GetService("SoundService")
local InterfaceSounds = SoundService:FindFirstChild("InterfaceSounds")
local ButtonSound = InterfaceSounds:WaitForChild("ButtonSound")
local HoverSound = InterfaceSounds:WaitForChild("HoverSound")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvents = ReplicatedStorage:FindFirstChild("RemoteEvents")
local SinglePlayerAsync = RemoteEvents:WaitForChild("SinglePlayerAsync")

local Player = game.Players.LocalPlayer

local PlayerGui = Player.PlayerGui
local TitleInterface = PlayerGui.TitleInterface

local SinglePlayer = TitleInterface["1P Play"]
local Layer = SinglePlayer.Layer

local TweenService = game:GetService("TweenService")

local debounce = false

local HighlightButton = TweenService:Create(
	SinglePlayer,
	TweenInfo.new(0.5),
	{Size = UDim2.new(0.3, 0, 0.125, 0)}
)


local UnhighlightButton = TweenService:Create(
	SinglePlayer,
	TweenInfo.new(0.5),
	{Size = UDim2.new(0.2, 0, 0.1, 0)}
)

local HighlightLayer = TweenService:Create(
	Layer,
	TweenInfo.new(0.5),
	{BackgroundTransparency = 0.25}
)


local UnhighlightLayer = TweenService:Create(
	Layer,
	TweenInfo.new(0.5),
	{BackgroundTransparency = 1}
)


SinglePlayer.MouseEnter:Connect(function()
	HoverSound:Play()
	HighlightButton:Play()
	HighlightLayer:Play()
end)


SinglePlayer.MouseLeave:Connect(function()
	UnhighlightButton:Play()
	UnhighlightLayer:Play()
end)


SinglePlayer.MouseButton1Click:Connect(function()
	ButtonSound:Play()
	SinglePlayerAsync:FireServer()
end)

The teleporter (server)

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvents = ReplicatedStorage:FindFirstChild("RemoteEvents")
local SinglePlayerAsync = RemoteEvents:WaitForChild("SinglePlayerAsync")

local TeleportService = game:GetService("TeleportService")
local PlaceId = 89365024397198

local teleportData = {
	minimumPlayers = 1,
}

local TeleportOptions = Instance.new("TeleportOptions")
TeleportOptions.Name = "TeleportOptions"
TeleportOptions.ShouldReserveServer = true

TeleportOptions:SetTeleportData(teleportData)

SinglePlayerAsync.OnServerEvent:Connect(function(Player)
	TeleportService:TeleportAsync(PlaceId, {Player}, TeleportOptions)
end)

The chat messages handler (local script)

local StarterGui = game:GetService("StarterGui")
local arrived

local MessageLength = 60

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvents = ReplicatedStorage:FindFirstChild("RemoteEvents")
local SinglePlayerActivated = RemoteEvents:WaitForChild("SinglePlayerActivated")

local debounce = false

-- this runs for players who join later on, not the player who joined initially.
game.Players.PlayerAdded:Connect(function(Player)
	local text = "[S] "..Player.Name.." has arrived!"
	local color = Color3.fromRGB(255, 234, 197)
	
	while not arrived do
		arrived = pcall(StarterGui.SetCore, StarterGui, "ChatMakeSystemMessage", {Text = text, Color = color})
		task.wait(1)
		if arrived then -- if success is equal to true.
			break
		end
	end
end)


-- single player messages.
SinglePlayerActivated.OnClientEvent:Connect(function(text, color)
	local activated, errormessage = pcall(function()
		print("B")
		StarterGui:SetCore("ChatMakeSystemMessage", {Text = text, Color = color})
	end)
	
	if activated then
		return activated
	else
		warn(errormessage)
	end
end)


-- global server messages.
local function AutomatedMessages(text, color)
	local global
	
	while not global do
		global = pcall(StarterGui.SetCore, StarterGui, "ChatMakeSystemMessage", {Text = text, Color = color})
		task.wait(1)
		if global then
			global = nil
			break
		end
	end
end


while true do
	local Probability = math.random(1, 4)
	if Probability == 1 then
		AutomatedMessages("[S] 1P is now available!", Color3.fromRGB(111, 204, 255))
	elseif Probability == 2 then
		AutomatedMessages("[S] Global Leaderboards have been added!", Color3.fromRGB(255, 131, 249))
	elseif Probability == 3 then
		AutomatedMessages("[S] Fight your rivals and make your way to the top!", Color3.fromRGB(255, 206, 0))
	elseif Probability == 4 then
		AutomatedMessages("[S] Servers may shut down for patch updates.", Color3.fromRGB(255, 131, 135))
	end
	task.wait(MessageLength)
end

The round (module)

local mod = {}

local minimumPlayers = 2

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvents = ReplicatedStorage:FindFirstChild("RemoteEvents")
local Skydive = RemoteEvents:WaitForChild("Skydive")
local SinglePlayerActivated = RemoteEvents:WaitForChild("SinglePlayerActivated")

local SoundService = game:GetService("SoundService")
local GlobalSounds = SoundService.GlobalSounds
local CountdownSound = GlobalSounds.CountdownSound
local Awarded = GlobalSounds.Awarded

local debounce = false

game.Players.PlayerAdded:Connect(function(Player)
	local JoinData = Player:GetJoinData()
	if JoinData then
		local TeleportData = JoinData.TeleportData
		if TeleportData then
			minimumPlayers = TeleportData.minimumPlayers -- changes the minimum players to 1.
			print("A")
			SinglePlayerActivated:FireClient(Player, "[S] Single player has been turned on. Have fun!", Color3.fromRGB(111, 204, 255))
		end
	end
end)




function mod:Intermission(Players, Status, Intermission, IntermissionLength)
	local function EnoughPlayers()
		for i = 0, 3, 1 do
			Status.Value = "Waiting for more players to join"..string.rep(".", i)
			task.wait(1)
		end
	end

	repeat EnoughPlayers() task.wait() until #Players:GetPlayers() >= minimumPlayers

	repeat task.wait() until #Players:GetPlayers() >= minimumPlayers
	-- set the intermission value to true
	Intermission.Value = true

	for i = IntermissionLength, 0, -1 do
		Status.Value = "Intermission: "..tostring(i)
		task.wait(1)
	end

	Intermission.Value = false
end




function mod:StartRound(Players, Status, Arena, TeleportTo)
	-- start the round
	for i, player in pairs(Players:GetPlayers()) do
		local Character = player.Character or player.CharacterAdded:Wait()
		if Character then
			local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
			if HumanoidRootPart then
				player:SetAttribute("InRound", true)
				if player:GetAttribute("InRound") then
					HumanoidRootPart:PivotTo(TeleportTo.CFrame)
					Skydive:FireClient(player)
				end
			end
		end
	end
	
	for i = 3, 1, -1 do
		Status.Value = tostring(i).. "..."
		CountdownSound:Play()
		task.wait(1)
	end
	CountdownSound:Play()
	Status.Value = "GO!"

	Arena.BrickColor = BrickColor.random()
	task.wait(2)
	Arena.CanCollide = false
	Status.Value = "Round in progress!"
end




function mod:EndRound(Players, Status, DisgardLength, Arena, Target, LobbySpawn, RoundEnded)
	-- end the round
	local Winners = {}
	
	local rewardedGloryPoints = math.random(100, 300)
	local rewardedGloryCoins = math.random(25, 50)
	
	local rewardChance = math.random(1, 4)
	local rewardBoost = 3
	
	local hasClearedTable = false
	
	local function NoWinnersFound()
		task.wait(DisgardLength)
		if #Winners == 0 and hasClearedTable == false then -- if there are no winners after 35 seconds.
			Status.Value = "No winners! Disbanding round!"
			if Arena.CanCollide == false then
				Arena.CanCollide = true
			end
		end
	end
	
	Target.Touched:Connect(function(Hit)
		local Player = Players:GetPlayerFromCharacter(Hit.Parent)
		
		if Player then
			if not table.find(Winners, Player) then -- if it's not the same player.
				table.insert(Winners, Player) -- then insert them into the table.
			end
			
			local Character = Player.Character or Player.CharacterAdded:Wait()
			if Character then
				local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
				if HumanoidRootPart then
					Player:SetAttribute("InRound", false)
					if not Player:GetAttribute("InRound") then
						HumanoidRootPart:PivotTo(LobbySpawn.CFrame + Vector3.new(0, 10, 0))
					end
					Arena.CanCollide = true
					for i, winner in pairs(Winners) do
						if table.find(Winners, Player) then -- checks if the player is a winner.
							if not debounce then
								debounce = true
								Status.Value = "Winner(s): "..winner.Name
								if rewardChance == 3 then
									-- triples rewards gained from round.
									Awarded:Play()
									Status.Value = "["..Player.Name.."]".." received tripled rewards!"
									Player.leaderstats["Glory Points"].Value += (rewardedGloryPoints * rewardBoost)
									Player.leaderstats["Glory Coins"].Value += (rewardedGloryCoins * rewardBoost)
								else
									Player.leaderstats["Glory Points"].Value += rewardedGloryPoints
									Player.leaderstats["Glory Coins"].Value += rewardedGloryCoins
								end
								task.wait(3)
								debounce = false
							end
						end
						task.wait(1)
					end
					table.clear(Winners) -- clears the table of previous winners.
					hasClearedTable = true
					RoundEnded.Value = true
					task.wait(3)
					RoundEnded.Value = false
				end
			end
		end
	end)
	
	if hasClearedTable ~= true then
		repeat if hasClearedTable == true then
				hasClearedTable = false
			else
				NoWinnersFound()
			end
			task.wait(1)
		until hasClearedTable == false
	end
end



return mod

If I am doing something wrong, please correct me.

I’m not sure what’s causing this. But I will continue to look for solutions.

Edit: So have you revised the code?

Figured out that is has something to do with .OnClientEvent:

-- (this fires only once)
local activated, errormessage = pcall(function()
	print("B")
	StarterGui:SetCore("ChatMakeSystemMessage", {Text = text, Color = color})
end)

if activated then
	print(activated)
else
	warn(errormessage)
end

-- single player messages. (this fires twice when put in the .OnClientEvent function)
SinglePlayerActivated.OnClientEvent:Connect(function(text, color)
	--local activated, errormessage = pcall(function()
	--	print("B")
	--	StarterGui:SetCore("ChatMakeSystemMessage", {Text = text, Color = color})
	--end)
	
	--if activated then
	--	print(activated)
	--else
	--	warn(errormessage)
	--end
end)

Maybe then put it inside a function and call it:

function Message(text,color)
   local activated, errormessage = pcall(function()
	   print("B")
	   StarterGui:SetCore("ChatMakeSystemMessage", {Text = text, Color = color})
   end)
   
   if activated then
	   print(activated)
   else
	   warn(errormessage)
   end
end

SinglePlayerActivated.OnClientEvent:Connect(function(text, color)
	Message(text,color)
end)
1 Like

I have no idea how, but I just waited for 1 to 2 seconds and it worked.

-- single player messages.
SinglePlayerActivated.OnClientEvent:Connect(function(text, color)
	task.wait(1)
	ActivatedMessage(text, color)
end)


function ActivatedMessage(text, color)
	local activated, errormessage = pcall(function()
		print("B")
		StarterGui:SetCore("ChatMakeSystemMessage", {Text = text, Color = color})
	end)

	if activated then
		print(activated)
	else
		warn(errormessage)
	end
end

Does anyone have an explanation as to why waiting after .OnClientEvent works?

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