HOW to stop multiple threads with bindable events?

I want to simply pass some variables and triggers between scripts. Enter bindables. But - I notice that when an event is triggered, its a separate ‘thread’, it just keeps going, and the next does its own thing on top, and the next does the same, and the next. How do i make that not happen? Or whats an alternative?
It really seems like i need a primer on this because i cannot follow the logic.

Im using collectionservice to see if a ‘cat’ has caught the ‘mouse’. This check is wrapped up in a function that triggers everytime that a random mouse player has been selected in another script and the moment that playerchar enters the game. a tool is added (the instrument) to the backpack etc. but i now get multiple tools added in at a linear rate. and when i look at the prints in the output, i see it repeat twice, repeat three times, repeat four times. the touch events also go up enormously. because those threads are running on top of each other i guess.

How do i tell the thread to STOP when the mouse is caught?

mousecatch check script:

--get services
local CollectionService = game:GetService("CollectionService")
local mouseplayer

-- get mouseplayer 
local mouseCharSelectedEVENT = game.ServerScriptService.SelectRandomMouse.MouseCharSelected

--variables
local connection
local mousecaught = false


-- FUNCTIONS
local function detectMouseCatch()
	print(mousecaught)
	for _, cat in CollectionService:GetTagged("cat") do -- everything tagged 'cat' runs this
		for _, part in ipairs(cat:GetChildren()) do -- for every part in a cat
			if mousecaught == true then -- IF the mouse has been caught
				break --stop
			else
				if part:IsA("BasePart") then --for every verified child that is a part
					if mousecaught == true then -- IF the mouse has been caught
						break --stop
					else -- otherwise go on:
						connection = part.Touched:Connect(function(hit) --connect to the regularly checking 'touched' function
							print(mousecaught)
							if mousecaught == true then -- if the mouse has been caught
								return -- stop
							else -- otherwise:
								if hit.Parent.Name == "Mouse" then -- then when the cat's part touched something see if parent is mouse
									connection:Disconnect() -- if so, disconnect from touched event so this part is registered only once
									local mouse = hit.Parent -- the parent then is the mouse
									mousecaught = true -- the mouse has been caught!
									print(hit)
									script.MouseCaughtEvent:Fire() -- tell everybody mouse is caught
									mouseplayer.Character.Humanoid.Health = 0 --set mouse player health to zero
									
									for _, mousepart in ipairs(mouse:GetChildren()) do -- for every obj in the mouse
										if mousepart.Name == "MiddlePart" then
											-- was supposed to move mouse to mouth of cat but cannot set position on part of tool

										end
										if mousepart.ClassName == "Part" then -- if its a part
											mousepart.Anchored = true -- anchor the parts

										end
									end	

									-- add CAUGHT gui (BY playername!!/YOU)
									-- add CAUGHT sound (bite sound, TJING)
									if cat.ClassName == "Player" then
										-- get points
									end
								end
							
							end
						end)
					end
				end
			end	
		end
	end

end
	

--EVENTS
mouseCharSelectedEVENT.Event:Connect(function(sentmouseplayer)
	print("mouseplayer sent event")
	mouseplayer = sentmouseplayer -- receive who is the mouseplayer
	if mouseplayer then 
		mouseplayer.CharacterAdded:Connect(function() -- when mouseplayer enters game
			mousecaught = false -- the mouse is no longer 'caught'
			detectMouseCatch() -- see what touches/catches it then
			print("when character gets added in mousecaught")
		end)
	end
end)

select random player and equip instrument

--Services and Variables
local ServerScriptService = game:GetService("ServerScriptService")
local playerservice = game:GetService("Players")
playerservice.PlayerAdded:Wait() -- this makes the script wait until a player has been added!!!!!

local players = playerservice:GetPlayers()


local RandomPlayer 
local mouseplayer
local newInstrument



-- Functions
local function getNewMousePlayer()
RandomPlayer = players[math.random(1, #players)] -- random number between 1 and amount of players
mouseplayer = RandomPlayer
	
script.MouseCharSelected:Fire(mouseplayer) -- this fires the bindable event and sends the mouseplayer
end

local function setInstrumentToMouseplayer ()
	local mouseplayerchar = mouseplayer.Character or mouseplayer.CharacterAdded:Wait()
	local instrument = game.ServerStorage["The Instrument"]
	newInstrument = instrument:Clone()
	newInstrument.Parent = mouseplayer.Backpack -- put tool in backpack
	mouseplayerchar.Humanoid:EquipTool(newInstrument) -- equip tool to mouseplayer
end


-- Do above functions at start of game
getNewMousePlayer()
setInstrumentToMouseplayer()


-- Receive events
mouseCaughtEVENT = ServerScriptService.MouseCaught.MouseCaughtEvent
mouseCaughtEVENT.Event:Connect(function() -- connecting to when the mouse is caught
	print("mousecaughtevent received")
	newInstrument:Destroy()
	mouseplayer.CharacterAdded:Connect(function()
	getNewMousePlayer() -- set a new mouseplayer
	setInstrumentToMouseplayer() -- set the instrument to a new mouseplayer
	print("when character gets added in randomouse")
	end)
end)
-- events are COROUTINES!!! if theyre fired multiple times
-- at the same time, they'll run concurrently
-- if event is fired multiple times, then on char add
-- the mouseplayer is randomly set multiple times
-- and the instrument is created and equipped multiple times
-- do check whether there's already an instrument?


additionally, the output:

false - Server - MouseCaught:15
23:37:35.178 when character gets added in mousecaught - Server - MouseCaught:75
23:37:35.996 :arrow_forward: false (x18) - Server - MouseCaught:26
23:37:38.159 Head - Server - MouseCaught:34
23:37:38.162 mousecaughtevent received - Server - SelectRandomMouse:41
23:37:38.175 :arrow_forward: true (x5) - Server - MouseCaught:26
23:37:43.611 when character gets added in randomouse - Server - SelectRandomMouse:46
23:37:43.611 false - Server - MouseCaught:15
23:37:43.612 when character gets added in mousecaught - Server - MouseCaught:75
23:37:43.612 mouseplayer sent event - Server - MouseCaught:69
23:37:43.615 :arrow_forward: false (x5) - Server - MouseCaught:26
23:37:43.702 Nose - Server - MouseCaught:34
23:37:43.706 :arrow_forward: true (x7) - Server - MouseCaught:26
23:37:43.708 mousecaughtevent received - Server - SelectRandomMouse:41
23:37:43.713 :arrow_forward: true (x4) - Server - MouseCaught:26
23:37:49.190 when character gets added in randomouse - Server - SelectRandomMouse:46
23:37:49.190 false - Server - MouseCaught:15
23:37:49.190 when character gets added in mousecaught - Server - MouseCaught:75
23:37:49.191 when character gets added in randomouse - Server - SelectRandomMouse:46
23:37:49.191 false - Server - MouseCaught:15
23:37:49.192 when character gets added in mousecaught - Server - MouseCaught:75
23:37:49.192 :arrow_forward: mouseplayer sent event (x2) - Server - MouseCaught:69
23:37:49.195 :arrow_forward: false (x21) - Server - MouseCaught:26
23:37:49.841 Tail - Server - MouseCaught:34
23:37:49.844 :arrow_forward: true (x7) - Server - MouseCaught:26
23:37:49.845 mousecaughtevent received - Server - SelectRandomMouse:41
23:37:50.058 :arrow_forward: true (x96) - Server - MouseCaught:26
23:37:55.289 when character gets added in randomouse - Server - SelectRandomMouse:46
23:37:55.289 false - Server - MouseCaught:15
23:37:55.289 when character gets added in mousecaught - Server - MouseCaught:75
23:37:55.289 false - Server - MouseCaught:15
23:37:55.290 when character gets added in mousecaught - Server - MouseCaught:75
23:37:55.291 when character gets added in randomouse - Server - SelectRandomMouse:46
23:37:55.291 false - Server - MouseCaught:15
23:37:55.291 when character gets added in mousecaught - Server - MouseCaught:75
23:37:55.293 when character gets added in randomouse - Server - SelectRandomMouse:46
23:37:55.293 false - Server - MouseCaught:15
23:37:55.293 when character gets added in mousecaught - Server - MouseCaught:75
23:37:55.293 :arrow_forward: mouseplayer sent event (x3) - Server - MouseCaught:69
23:37:56.024 false - Server - MouseCaught:26
23:37:56.024 Tail - Server - MouseCaught:34
23:37:56.030 :arrow_forward: true (x15) - Server - MouseCaught:26
23:37:56.035 mousecaughtevent received - Server - SelectRandomMouse:41
23:38:01.467 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:01.468 false - Server - MouseCaught:15
23:38:01.468 when character gets added in mousecaught - Server - MouseCaught:75
23:38:01.469 false - Server - MouseCaught:15
23:38:01.469 when character gets added in mousecaught - Server - MouseCaught:75
23:38:01.470 false - Server - MouseCaught:15
23:38:01.471 when character gets added in mousecaught - Server - MouseCaught:75
23:38:01.475 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:01.475 false - Server - MouseCaught:15
23:38:01.476 when character gets added in mousecaught - Server - MouseCaught:75
23:38:01.476 false - Server - MouseCaught:15
23:38:01.477 when character gets added in mousecaught - Server - MouseCaught:75
23:38:01.480 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:01.481 false - Server - MouseCaught:15
23:38:01.481 when character gets added in mousecaught - Server - MouseCaught:75
23:38:01.484 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:01.484 false - Server - MouseCaught:15
23:38:01.485 when character gets added in mousecaught - Server - MouseCaught:75
23:38:01.485 :arrow_forward: mouseplayer sent event (x4) - Server - MouseCaught:69
23:38:01.990 false - Server - MouseCaught:26
23:38:01.990 Nose - Server - MouseCaught:34
23:38:01.993 :arrow_forward: true (x29) - Server - MouseCaught:26
23:38:01.998 mousecaughtevent received - Server - SelectRandomMouse:41
23:38:07.423 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:07.423 false - Server - MouseCaught:15
23:38:07.423 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.423 false - Server - MouseCaught:15
23:38:07.423 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.424 false - Server - MouseCaught:15
23:38:07.424 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.424 false - Server - MouseCaught:15
23:38:07.424 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.425 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:07.425 false - Server - MouseCaught:15
23:38:07.426 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.426 false - Server - MouseCaught:15
23:38:07.426 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.426 false - Server - MouseCaught:15
23:38:07.427 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.428 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:07.428 false - Server - MouseCaught:15
23:38:07.428 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.428 false - Server - MouseCaught:15
23:38:07.428 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.429 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:07.430 false - Server - MouseCaught:15
23:38:07.430 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.431 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:07.431 false - Server - MouseCaught:15
23:38:07.431 when character gets added in mousecaught - Server - MouseCaught:75
23:38:07.432 :arrow_forward: mouseplayer sent event (x5) - Server - MouseCaught:69
23:38:08.606 false - Server - MouseCaught:26
23:38:08.607 Head - Server - MouseCaught:34
23:38:08.611 :arrow_forward: true (x103) - Server - MouseCaught:26
23:38:08.630 mousecaughtevent received - Server - SelectRandomMouse:41
23:38:14.056 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:14.056 false - Server - MouseCaught:15
23:38:14.056 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.056 false - Server - MouseCaught:15
23:38:14.057 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.057 false - Server - MouseCaught:15
23:38:14.057 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.057 false - Server - MouseCaught:15
23:38:14.058 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.058 false - Server - MouseCaught:15
23:38:14.058 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.060 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:14.060 false - Server - MouseCaught:15
23:38:14.061 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.061 false - Server - MouseCaught:15
23:38:14.061 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.062 false - Server - MouseCaught:15
23:38:14.062 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.062 false - Server - MouseCaught:15
23:38:14.063 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.064 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:14.064 false - Server - MouseCaught:15
23:38:14.065 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.065 false - Server - MouseCaught:15
23:38:14.065 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.065 false - Server - MouseCaught:15
23:38:14.066 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.067 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:14.067 false - Server - MouseCaught:15
23:38:14.067 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.068 false - Server - MouseCaught:15
23:38:14.068 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.070 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:14.070 false - Server - MouseCaught:15
23:38:14.070 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.072 when character gets added in randomouse - Server - SelectRandomMouse:46
23:38:14.072 false - Server - MouseCaught:15
23:38:14.072 when character gets added in mousecaught - Server - MouseCaught:75
23:38:14.073 :arrow_forward: mouseplayer sent event (x6) - Server - MouseCaught:69
23:38:14.454 false - Server - MouseCaught:26
23:38:14.455 Tail - Server - MouseCaught:34
23:38:14.464 :arrow_forward: true (x167) - Server - MouseCaught:26
23:38:14.515 mousecaughtevent received - Server - SelectRandomMouse:41

1 Like

I believe signal behavior is deferred by default (which is a property set in Workspace), making event triggering asynchronous. To get that “immediate” response for what you’re doing, consider using BindableFunctions instead, which is synchronous.
If you want to avoid refactoring your code, you can change that Workspace property called SignalBehavior to immediate, but this can affect overall performance depending how many connections you have.

2 Likes

Thank you very much for your response!

I will try changing things over to bindable functions. But…what is the use case for events then? I dont get it.

I also put these two scripts together into one script, eliminating bindables. And i found that I now have a problem where im trying to call functions before they’re defined, because each function calls the other… does that mean the logic flow is fundamentally wrong?
see

--get services
local CollectionService = game:GetService("CollectionService")
local mouseplayer

local ServerScriptService = game:GetService("ServerScriptService")
local playerservice = game:GetService("Players")
playerservice.PlayerAdded:Wait() -- this makes the script wait until a player has been added!!!!!

local players = playerservice:GetPlayers()


-- get mouseplayer 
local mouseCharSelectedEVENT = game.ServerScriptService.SelectRandomMouse.MouseCharSelected

--variables
local connection
local mousecaught = false

local RandomPlayer 
local mouseplayer
local newInstrument

-- FUNCTIONS

local function getNewMousePlayer()
	RandomPlayer = players[math.random(1, #players)] -- random number between 1 and amount of players
	mouseplayer = RandomPlayer
	mouseplayer.CharacterAdded:Connect(function() -- when mouseplayer enters game
		mousecaught = false -- the mouse is no longer 'caught'
		detectMouseCatch() -- see what touches/catches it then
		print("when character gets added")
	end)
end

local function setInstrumentToMouseplayer ()
	local mouseplayerchar = mouseplayer.Character or mouseplayer.CharacterAdded:Wait()
	local instrument = game.ServerStorage["The Instrument"]
	newInstrument = instrument:Clone()
	newInstrument.Parent = mouseplayer.Backpack -- put tool in backpack
	mouseplayerchar.Humanoid:EquipTool(newInstrument) -- equip tool to mouseplayer
end


local function detectMouseCatch()
	print(mousecaught)
	for _, cat in CollectionService:GetTagged("cat") do -- everything tagged 'cat' runs this
		for _, part in ipairs(cat:GetChildren()) do -- for every part in a cat
			if mousecaught == true then -- IF the mouse has been caught
				break --stop
			else
				if part:IsA("BasePart") then --for every verified child that is a part
					if mousecaught == true then -- IF the mouse has been caught
						break --stop
					else -- otherwise go on:
						connection = part.Touched:Connect(function(hit) --connect to the regularly checking 'touched' function
							print(mousecaught)
							if mousecaught == true then -- if the mouse has been caught
								return -- stop
							else -- otherwise:
								if hit.Parent.Name == "Mouse" then -- then when the cat's part touched something see if parent is mouse
									connection:Disconnect() -- if so, disconnect from touched event so this part is registered only once
									local mouse = hit.Parent -- the parent then is the mouse
									mousecaught = true -- the mouse has been caught!
									print(hit)
									
									newInstrument:Destroy() -- the instrument is destroyed in mouseplayer						
									mouseplayer.Character.Humanoid.Health = 0 --set mouse player health to zero
									
									getNewMousePlayer() -- set a new mouseplayer
									setInstrumentToMouseplayer() -- set the instrument to a new mouseplayer

									for _, mousepart in ipairs(mouse:GetChildren()) do -- for every obj in the mouse
										if mousepart.Name == "MiddlePart" then
											-- was supposed to move mouse to mouth of cat but cannot set position on part of tool

										end
										if mousepart.ClassName == "Part" then -- if its a part
											mousepart.Anchored = true -- anchor the parts

										end
									end	

									-- add CAUGHT gui (BY playername!!/YOU)
									-- add CAUGHT sound (bite sound, TJING)
									if cat.ClassName == "Player" then
										-- get points
									end
								end

							end
						end)
					end
				end
			end	
		end
	end

end

-- Do above functions at start of game
getNewMousePlayer()
setInstrumentToMouseplayer()


trying to cut it out of the function doesnt seem to help: the prints dont output, the event doesnt seem to be connected…


if mouseplayerknown then
mouseplayer.CharacterAdded:Connect(function() -- when mouseplayer enters game
	print("added?")
	mousecaught = false -- the mouse is no longer 'caught'
	detectMouseCatch() -- see what touches/catches it then
	print("when character gets added")
end)
end
1 Like

I don’t get what the script is trying to do, any way you could simplify it for me? Also, you might be able to troubleshoot a bit better if you organize your code a bit better. For example, if you could simplify the following:

if part:IsA("BasePart") or mousecaught then return end

this one line does basically the same thing as

if mousecaught == true then -- IF the mouse has been caught
				break --stop
			else
				if part:IsA("BasePart") then

once you explain the code does then I can for sure help you out!

I cut out all bindable events and put it all into one script. It seems the problem is not (entirely) because of the synchronous nature of events. Maybe its because of the synchronous nature of collectionservice?

every ‘round’ the startround function and the detectmouse function (or basically everything) is called an additional time… (see the ‘hello yeah’ print)

false - Server - Monsterscript:53
01:08:24.671 :arrow_forward: false (x31) - Server - Monsterscript:64
01:08:28.931 Nose - Server - Monsterscript:72
01:08:31.532 :arrow_forward: true (x14) - Server - Monsterscript:64
01:08:34.395 hello yeah - Server - Monsterscript:48
01:08:35.746 :arrow_forward: false (x16) - Server - Monsterscript:64
01:08:41.113 Nose - Server - Monsterscript:72
01:08:45.597 :arrow_forward: true (x28) - Server - Monsterscript:64
01:08:46.540 ▼ hello yeah (x2) - Server - Monsterscript:48
01:08:46.541 hello yeah
01:08:46.728 :arrow_forward: false (x3) - Server - Monsterscript:64
01:08:47.615 Head - Server - Monsterscript:72
01:08:47.624 :arrow_forward: true (x55) - Server - Monsterscript:64
01:08:53.050 ▼ hello yeah (x3) - Server - Monsterscript:48
01:08:53.051 hello yeah
01:08:53.051 hello yeah
01:08:53.248 :arrow_forward: false (x2) - Server - Monsterscript:64
01:08:53.846 Tail - Server - Monsterscript:72
01:08:54.484 :arrow_forward: true (x62) - Server - Monsterscript:64
01:08:59.296 :arrow_forward: hello yeah (x4) - Server - Monsterscript:48
01:08:59.412 :arrow_forward: false (x4) - Server - Monsterscript:64
01:09:00.916 Tail - Server - Monsterscript:72
01:09:00.926 :arrow_forward: true (x13) - Server - Monsterscript:64
01:09:06.331 :arrow_forward: hello yeah (x5) - Server - Monsterscript:48

latest version:

--get services
local CollectionService = game:GetService("CollectionService")
local mouseplayer

local ServerScriptService = game:GetService("ServerScriptService")
local playerservice = game:GetService("Players")
playerservice.PlayerAdded:Wait() -- this makes the script wait until a player has been added!!!!!

local players = playerservice:GetPlayers()


--variables
local connection
local mousecaught = false

local RandomPlayer 
local mouseplayer
local newInstrument
local mouseplayerknown

-- FUNCTIONS

local function getNewMousePlayer()
	RandomPlayer = players[math.random(1, #players)] -- random number between 1 and amount of players
	mouseplayer = RandomPlayer
	mouseplayerknown = true
end

local function setInstrumentToMouseplayer ()
	local mouseplayerchar = mouseplayer.Character or mouseplayer.CharacterAdded:Wait()
	local instrument = game.ServerStorage["The Instrument"]
	newInstrument = instrument:Clone()
	newInstrument.Parent = mouseplayer.Backpack -- put tool in backpack
	mouseplayerchar.Humanoid:EquipTool(newInstrument) -- equip tool to mouseplayer
end

local function startRound()
	mouseplayer.CharacterRemoving:Connect(function() -- when mouseplayerchar despawns
		getNewMousePlayer()
		setInstrumentToMouseplayer()
	end)
	
	mouseplayer.CharacterAdded:Connect(function() -- when mouseplayerchar respawns 
	mousecaught = false
	print("hello yeah")
	end)
end

local function detectMouseCatch()
	print(mousecaught)
	for _, cat in CollectionService:GetTagged("cat") do -- everything tagged 'cat' runs this
		for _, part in ipairs(cat:GetChildren()) do -- for every part in a cat
			if mousecaught == true then -- IF the mouse has been caught
				break --stop
			else
				if part:IsA("BasePart") then --for every verified child that is a part
					if mousecaught == true then -- IF the mouse has been caught
						break --stop
					else -- otherwise go on:
						connection = part.Touched:Connect(function(hit) --connect to the regularly checking 'touched' function
							print(mousecaught)
							if mousecaught == true then -- if the mouse has been caught
								return -- stop
							else -- otherwise:
								if hit.Parent.Name == "Mouse" then -- then when the cat's part touched something see if parent is mouse
									connection:Disconnect() -- if so, disconnect from touched event so this part is registered only once
									local mouse = hit.Parent -- the parent then is the mouse
									mousecaught = true -- the mouse has been caught!
									print(hit)
									
									newInstrument:Destroy() -- the instrument is destroyed in mouseplayer						
									mouseplayer.Character.Humanoid.Health = 0 --set mouse player health to zero
									startRound()

									for _, mousepart in ipairs(mouse:GetChildren()) do -- for every obj in the mouse
										if mousepart.Name == "MiddlePart" then
											-- was supposed to move mouse to mouth of cat but cannot set position on part of tool

										end
										if mousepart.ClassName == "Part" then -- if its a part
											mousepart.Anchored = true -- anchor the parts

										end
									end	

									-- add CAUGHT gui (BY playername!!/YOU)
									-- add CAUGHT sound (bite sound, TJING)
									if cat.ClassName == "Player" then
										-- get points
									end
								end

							end
						end)
					end
				end
			end	
		end
	end

end

-- Do above functions at start of game
getNewMousePlayer()
setInstrumentToMouseplayer()
detectMouseCatch()

-- learned from this that detectmouscatch need not be called by anything, setting the mousecaught variable to false is enough...

Hey Doordash, thanks for your response.

I put that bit in because i was trying to suss out why I was getting repetitions and thought it had something to do with the forloops iterating over every part in the ‘cat’ to see if they’d touched anything. So I put in an if ->break. Im not sure about those bits, actually. And it seems like if → return does the same thing as if → break then? Or not?

I actually break up every ‘logic step’ in the code because i find that easier to read and debug. What is it that’s not clear about what I’m trying to do?

1 Like

Hi! Yeah do what works for you, I used to have a hard time debugging my earlier scripts because I had too many different if else statements, making print testing difficult, thats why I suggested condensing the if and else statements.

Breaks are used for loops to exit a loop, while return is generally used in functions to spit back a certain piece of value. If you return without adding anything after, the return value will be nil.

Since you are getting multiple print values, my guess is that the second break:

if part:IsA("BasePart") then --for every verified child that is a part
					if mousecaught == true then -- IF the mouse has been caught
						break --stop
					else -- otherwise go on:

is exiting the second loop back into the first one, so maybe try printing the variables cat and part to see if they are giving you the values you are looking for.

Although you might have different plans for the game, why not just run mouse detection on the client? Once a player finds a mouse and hovers/clicks on it, fire an event to the server, which would give you both the player who found the mouse, alongside the name/id of the mouse. Then you could just remove said mouse from a “mouse list”, which is renewed at the beginning of the game.

I was super tired and could not understand the code for the life of me, thats why I asked you to clarify it for me. I reread through it now, and although it can be simplified, the confusion was 100% my fault. Good luck and send updates if you can get it working!

1 Like

I’ll respond to this when I get home.

Okay yeah I didn’t get to look at this too in-depth before but it looks like what I figured originally may still be the case. You’re not disconnecting the function properly.

Your variable for “connection” is global but you’re re-defining connection with part.Touched:Connect(function(hit) when you’re looping it.

What you’d be better off doing - if this is indeed your intention - is creating a connection table.

local Connections = {}
Instead of connection = part.Touched etc you’d do:

table.insert(Connections, part.Touched:Connect(function(hit)
end)) -- don't forget to close the parentheses.

Although there is more than just this that I’ve seen which makes the code all a bit messy. Let me see if I can re-create it with a simpler method and attempt to do what you’re aiming to do still. Give me just a moment.

Hello! thank you so much for looking at it. I was really busy with work so couldnt reply sooner. Just before, i managed to make it work, if im correct, in one big script.

it is for SURE is something about disconnecting events. In the last below script i disconnected the characteradded and characterremovingscripts. it seems to me that everytime the script was supposed to ‘restart’ it connected to the event on top of its first, second, third connection. I thought i figured it out and tried to fix the scripts that worked with events the same way.

But. this works for one character added event in the ‘selectrandommouse’ script:

-- Receive events
mouseCaughtEVENT = ServerScriptService.MouseCaught.MouseCaughtEvent
mouseCaughtEVENT.Event:Connect(function() -- connecting to when the mouse is caught
	print("mousecaughtevent received")
	newInstrument:Destroy()
	listenformouseplayerrespawn = mouseplayer.CharacterAdded:Connect(function()
	getNewMousePlayer() -- set a new mouseplayer
	setInstrumentToMouseplayer() -- set the instrument to a new mouseplayer
	print("when character gets added in randomouse")
	
	listenformouseplayerrespawn:Disconnect()
	end)
end)

I disconnect and it does not listen on top of listening on top of listening.
but when i try to apply the same thing to the ‘mouse caught’ script:

--EVENTS
mouseCharSelectedEVENT.Event:Connect(function(sentmouseplayer)
	print("mouseplayer sent event")
	mouseplayer = sentmouseplayer -- receive who is the mouseplayer
	if mouseplayer then 
		listenformouseplayerrespawn = mouseplayer.CharacterAdded:Connect(function() -- when mouseplayer enters game
			mousecaught = false -- the mouse is no longer 'caught'
			--detectMouseCatch() -- collectionservice is continuous so bool only needs to be flipped
			print("when character gets added in mousecaught")
			listenformouseplayerrespawn:Disconnect()
		end)
		
	end
end)

It only listens the first round and not thereafter. Could the reason be that the character has already respawned before the mouseplayer has been set in one script, sent over to the next etc.? I just realised that that IS it and the check in the next script isnt even necessary because the check is already done in the other.
ok!!! the problem i had is fixed.

But i am very curious about the table option for Touched and how i could clean it all up a bit as you say. please let me know if you have time and/or interest still in giving me some recommendations. Thank you!!

--get services
local CollectionService = game:GetService("CollectionService")
local mouseplayer

local ServerScriptService = game:GetService("ServerScriptService")
local playerservice = game:GetService("Players")
playerservice.PlayerAdded:Wait() -- this makes the script wait until a player has been added!!!!!

local players = playerservice:GetPlayers()


--variables
local connection
local mousecaught = false

local RandomPlayer 
local mouseplayer
local newInstrument
local mouseplayerknown

local listenformouseplayerrespawn
local listenformouseplayerdespawn

-- FUNCTIONS

local function getNewMousePlayer()
	RandomPlayer = players[math.random(1, #players)] -- random number between 1 and amount of players
	mouseplayer = RandomPlayer
	mouseplayerknown = true
end

local function setInstrumentToMouseplayer ()
	local mouseplayerchar = mouseplayer.Character or mouseplayer.CharacterAdded:Wait()
	local instrument = game.ServerStorage["The Instrument"]
	newInstrument = instrument:Clone()
	newInstrument.Parent = mouseplayer.Backpack -- put tool in backpack
	mouseplayerchar.Humanoid:EquipTool(newInstrument) -- equip tool to mouseplayer
end

local function startRound()
	print("how many times repeat?")
	listenformouseplayerdespawn = mouseplayer.CharacterRemoving:Connect(function() -- when mouseplayerchar despawns
		getNewMousePlayer()
		setInstrumentToMouseplayer()
		print("how many times repeat?")
		listenformouseplayerdespawn:Disconnect()
	end)
	
	listenformouseplayerrespawn = mouseplayer.CharacterAdded:Connect(function() -- when mouseplayerchar respawns 
	mousecaught = false
	print("hello yeah")
	listenformouseplayerrespawn:Disconnect()
	end)
end

local function detectMouseCatch()
	
	if mousecaught then return
	else
		print(mousecaught)
		for _, cat in CollectionService:GetTagged("cat") do -- everything tagged 'cat' runs this
			if mousecaught == true then -- IF the mouse has been caught
				break --stop
				else
				for _, part in ipairs(cat:GetChildren()) do -- for every part in a cat
					if mousecaught == true then -- IF the mouse has been caught
						break --stop
					else
						if part:IsA("BasePart") then --for every verified child that is a part
							if mousecaught == true then -- IF the mouse has been caught
								break --stop
							else -- otherwise go on:
								connection = part.Touched:Connect(function(hit) --connect to the regularly checking 'touched' function
									print(mousecaught)
									if mousecaught == true then -- if the mouse has been caught
										return -- stop
									else -- otherwise:
										if hit.Parent.Name == "Mouse" then -- then when the cat's part touched something see if parent is mouse
											connection:Disconnect() -- if so, disconnect from touched event so this part is registered only once
											local mouse = hit.Parent -- the parent then is the mouse
											mousecaught = true -- the mouse has been caught!
											print(hit)
											
											newInstrument:Destroy() -- the instrument is destroyed in mouseplayer						
											mouseplayer.Character.Humanoid.Health = 0 --set mouse player health to zero
											startRound()
											

											for _, mousepart in ipairs(mouse:GetChildren()) do -- for every obj in the mouse
												if mousepart.Name == "MiddlePart" then
													-- was supposed to move mouse to mouth of cat but cannot set position on part of tool

												end
												if mousepart.ClassName == "Part" then -- if its a part
													mousepart.Anchored = true -- anchor the parts

												end
											end	

											-- add CAUGHT gui (BY playername!!/YOU)
											-- add CAUGHT sound (bite sound, TJING)
											if cat.ClassName == "Player" then
												-- get points
											end
										end

									end
								end)
							end
						end
					end	
				end
			end
		end
	end
end
-- Do above functions at start of game
getNewMousePlayer()
setInstrumentToMouseplayer()
detectMouseCatch()
1 Like

Okay yeah that’s much better. Only change I would make is that your connection variable is only holding onto one touched event and being re-written over in your loop. Unless those parts are meant to retain those connections I would recommend this. This is based on your most recent code.

Otherwise you may find that the parts with the touch function are still touchable – which in your case those parts are going to disappear anyways but disconnecting the events properly will prevent future issues and memory leaks.

local CollectionService = game:GetService("CollectionService")
local mouseplayer

local ServerScriptService = game:GetService("ServerScriptService")
local playerservice = game:GetService("Players")
playerservice.PlayerAdded:Wait() -- this makes the script wait until a player has been added!!!!!

local players = playerservice:GetPlayers()


--variables
local connections = {}
local mousecaught = false

local RandomPlayer 
local mouseplayer
local newInstrument
local mouseplayerknown

local listenformouseplayerrespawn
local listenformouseplayerdespawn

-- FUNCTIONS

local function getNewMousePlayer()
	RandomPlayer = players[math.random(1, #players)] -- random number between 1 and amount of players
	mouseplayer = RandomPlayer
	mouseplayerknown = true
end

local function setInstrumentToMouseplayer ()
	local mouseplayerchar = mouseplayer.Character or mouseplayer.CharacterAdded:Wait()
	local instrument = game.ServerStorage["The Instrument"]
	newInstrument = instrument:Clone()
	newInstrument.Parent = mouseplayer.Backpack -- put tool in backpack
	mouseplayerchar.Humanoid:EquipTool(newInstrument) -- equip tool to mouseplayer
end

local function startRound()
	print("how many times repeat?")
	listenformouseplayerdespawn = mouseplayer.CharacterRemoving:Connect(function() -- when mouseplayerchar despawns
		getNewMousePlayer()
		setInstrumentToMouseplayer()
		print("how many times repeat?")
		listenformouseplayerdespawn:Disconnect()
	end)

	listenformouseplayerrespawn = mouseplayer.CharacterAdded:Connect(function() -- when mouseplayerchar respawns 
		mousecaught = false
		print("hello yeah")
		listenformouseplayerrespawn:Disconnect()
	end)
end

local function detectMouseCatch()

	if mousecaught then return
	else
		print(mousecaught)
		for _, cat in CollectionService:GetTagged("cat") do -- everything tagged 'cat' runs this
			if mousecaught == true then -- IF the mouse has been caught
				break --stop
			else
				for _, part in ipairs(cat:GetChildren()) do -- for every part in a cat
					if mousecaught == true then -- IF the mouse has been caught
						break --stop
					else
						if part:IsA("BasePart") then --for every verified child that is a part
							if mousecaught == true then -- IF the mouse has been caught
								break --stop
							else -- otherwise go on:
								table.insert(connections, part.Touched:Connect(function(hit) --connect to the regularly checking 'touched' function
									print(mousecaught)
									if mousecaught == true then -- if the mouse has been caught
										return -- stop
									else -- otherwise:
										if hit.Parent.Name == "Mouse" then -- then when the cat's part touched something see if parent is mouse
											for _,con in pairs(connections) do con:Disconnect() end connections = {}
											local mouse = hit.Parent -- the parent then is the mouse
											mousecaught = true -- the mouse has been caught!
											print(hit)

											newInstrument:Destroy() -- the instrument is destroyed in mouseplayer						
											mouseplayer.Character.Humanoid.Health = 0 --set mouse player health to zero
											startRound()


											for _, mousepart in ipairs(mouse:GetChildren()) do -- for every obj in the mouse
												if mousepart.Name == "MiddlePart" then
													-- was supposed to move mouse to mouth of cat but cannot set position on part of tool

												end
												if mousepart.ClassName == "Part" then -- if its a part
													mousepart.Anchored = true -- anchor the parts

												end
											end	

											-- add CAUGHT gui (BY playername!!/YOU)
											-- add CAUGHT sound (bite sound, TJING)
											if cat.ClassName == "Player" then
												-- get points
											end
										end

									end
								end))
							end
						end
					end	
				end
			end
		end
	end
end
-- Do above functions at start of game
getNewMousePlayer()
setInstrumentToMouseplayer()
detectMouseCatch()

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