FocusLost firing twice on my tool script

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!
    I’m making this death note game on roblox.
    The deathnote plays tween and fires a remote event when FocusLost is triggered, and enterpressed is true.

  2. What is the issue? Include screenshots / videos if possible!

For some reason, Focuslost is happening twice when focus of the textbox is lost.

This is the only instance of the script in ReplicatedStorage
image

The tool itself is then cloned and inserted into the players backpack when their character is generated with the correct role. (The role being “Kira”)
image

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I have searched and seen issues similar to this one, but so far none of the solutions work for me (such as Debounces or sanity checks)

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!

Here is the entire version of my Localscript, please excuse my mess.

local Tool = script.Parent
-- Set up GUI objects here.
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local playerGui = player.PlayerGui

local PrimaryGUI = 	playerGui["GUI-DEATHNOTE"]

local Book = PrimaryGUI.Book
local Rules = PrimaryGUI.RULES
local Page = Book.ImageLabel
local Input = Book.TextBox
local KillRemote = game.ReplicatedStorage["DEATH-NOTE"].KillPlayer



local yValueCount = 1

local Debounce = false
local dbtime = 0.1

local WritingSounds = game.ReplicatedStorage.Sounds.Deathnote_PencilSounds:GetDescendants()
local PageFlipSound = game.ReplicatedStorage.Sounds.Paper_Flip

-- Muh Tweens
local TweenService = game:GetService("TweenService")

-- POPOUT TWEEN - BOOK
local Popoutgoal = {}
	Popoutgoal.Position = UDim2.new(0.881, 0 ,0.708, 0)
	Popoutgoal.Rotation = 0

local TweenInfoOUT = TweenInfo.new(
	
	0.5, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.Out, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching its goal)
	0 -- DelayTime
	
	
)

local PopoutTween = TweenService:Create(Book, TweenInfoOUT, Popoutgoal)

-- POP BACK IN TWEEN - BOOK
local PopinGoal = {}
	PopinGoal.Position = UDim2.new(0.942, 0, 0.842, 0)
	PopinGoal.Rotation = 8
local TweenInfoIN = TweenInfo.new(
	
	
	2, -- Time
	Enum.EasingStyle.Quint, -- EasingStyle
	Enum.EasingDirection.Out, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching its goal)
	0 -- DelayTime


	
)
local PopinTween = TweenService:Create(Book, TweenInfoIN, PopinGoal)

-- RULE TWEENS OUT
local RULEgoalOUT = {}
RULEgoalOUT.Position = UDim2.new(0.653, 0,0.859, 0)
local RULEtweeninfo = TweenInfo.new(
	
	0.5, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.Out, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching its goal)
	0 -- DelayTime
	
)
local RULEtweenOUT = TweenService:Create(Rules, RULEtweeninfo, RULEgoalOUT)

-- do the same- just in the reverse.
-- RULE TWEENS IN
local RULEgoalIN = {}
RULEgoalIN.Position = UDim2.new(0.732, 0,0.859, 0)
local RULEtweeninfoIN = TweenInfo.new(
	
	1.25, -- Time
	Enum.EasingStyle.Quint, -- EasingStyle
	Enum.EasingDirection.Out, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching its goal)
	0 -- DelayTime
)
local RULEtweenIN = TweenService:Create(Rules, RULEtweeninfoIN, RULEgoalIN)


local function Popout()
	
	local Sound = game.ReplicatedStorage.Sounds.Writing
	
	
	PopoutTween:Play()
	RULEtweenOUT:Play()
	
	local UIS = game:GetService("UserInputService")
	UIS.InputBegan:Connect(function(_, typing)
		if typing then
			local CurrentWritingSound = WritingSounds[math.random(1, #WritingSounds)]
			
			CurrentWritingSound:Play()
				
		end
	end)


	
	
end

local MoveTextDown = TweenInfo.new(
	0.25, -- Time
	Enum.EasingStyle.Quint, -- EasingStyle
	Enum.EasingDirection.Out, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching its goal)
	0 -- DelayTime
)

local textboxYArray = {
	[1] = .1,
	[2] = .23,
	[3] = .35,
	[4] = .47,
	[5] = .59,
	[6] = .71
}

local function Writing(enterpressed)
	print("Focus Lost!")
	
	if not enterpressed then PopinTween:Play() RULEtweenIN:Play() return end
	if player ~= player then print("Sanity Check") return end
	if Debounce == true then print("gbygjhnika") return end
	Debounce = true


	if enterpressed == true then
	
		
		
		local EnteredText = Input.Text
		-- Take action with the text here.
		KillRemote:FireServer(EnteredText)
		
		local CreatedText = Input:Clone()
		
		
		-- theres probably a more efficent way to do this
	
		
		CreatedText.Position = Input.Position
		CreatedText.Text = Input.Text
		CreatedText.PlaceholderText = ""
		CreatedText.Parent = Book
		CreatedText.ZIndex = 7
		CreatedText.Interactable = false
		CreatedText.TextColor3 = Color3.new(0.517647, 0.517647, 0.517647)
		CreatedText.Name = "WrittenText"
		print(EnteredText)
		
		-- push the textinput downwards (relative to tiself) to prevent overlap
		-- Thank you Noma for the help (writing everything below, up to line 153.)

		if yValueCount >= 6 then 
			
			local Decendents = Book:GetDescendants()
			
			local NextPage = Book:FindFirstChild("ImageLabel"):Clone()
			NextPage.Parent = Book
			NextPage.Name = "NextPage"
			NextPage.Position = UDim2.new(0.88, 0,0.521, 0)
			NextPage.Size = UDim2.new(0.313, 0,0.999, 0)
			NextPage.ZIndex = 9
			
			local NextPageFlipGoal = {}
			NextPageFlipGoal.Size = Page.Size
			NextPageFlipGoal.Position = Page.Position
			
			local PagefliptweenInfo = TweenInfo.new(1)
			local PageFlipTween = TweenService:Create(NextPage, PagefliptweenInfo, NextPageFlipGoal) 
			
			PageFlipTween:Play()
			PageFlipSound:Play()
			
			PageFlipTween.Completed:Wait()
			NextPage:Destroy()
			
			for i, v in pairs(Decendents) do
				if Decendents[i].Name == "WrittenText" then
					Decendents[i]:Destroy()
				end
			end
			
			yValueCount = 0 
		end
		
		yValueCount += 1
		
		local MoveTextGoal = {}
		MoveTextGoal.Position = UDim2.new(0.359, 0, textboxYArray[yValueCount], 0)
		local MoveTextTween = TweenService:Create(Input, MoveTextDown, MoveTextGoal)
		MoveTextTween:Play()
		
		
		
		PopinTween:Play()
		RULEtweenIN:Play()
		

	end
	
	PopinTween:Play()
	RULEtweenIN:Play()
	
	task.wait(dbtime)
	Debounce = false

	
end


Input.Focused:Connect(Popout)
Input.FocusLost:Connect(Writing)

If additional details are needed, I will be happy to provide.

what I think is happening here is, theres a tool in starterpack and in the player. as seen as they’re both local scripts, they both get fired.

I would check if the player has the tool equipped in the writing function.

edit: nevermind, I just re-read the post

Do you know of any solution to this problem? I still haven’t gotten it fixed and so far I haven’t really seen anything on forums about a problem like this

This is almost certainly happening because multiple instances of the same LocalScript are running likely due to how the Tool is being cloned. Even though the original script is only in ReplicatedStorage, once it’s cloned into the player’s Backpack, that script gets duplicated too.

Since Input.FocusLost:Connect(Writing) exists in each copy, each one will run the function when the event fires, causing it to trigger twice (or more).

To fix it:

  • Add a check at the top of the script to ensure it only runs once. For example:
if script:GetAttribute("Initialized") then return end
script:SetAttribute("Initialized", true)
  • Or, better yet, make sure you’re only cloning the Tool once per session and destroying unused copies.

The issue isn’t with FocusLost, it’s with multiple listeners being active unintentionally.

Oh my god, thank so much. This issue was driving me insane.

1 Like

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