:FireClient() Not working

  1. What do you want to achieve? Basically have I have a Food contest game where you press buttons at the screen and the food shrinks down until its finished and move on to another random type of food.

  2. What is the issue? So I have a function in a module that get fired by the server side, and a local script that controls the button at the screen and when you reach a certain click you start with the next meal, I’ve made it so that the module fires the local script so that the ui get visible and starts counting, and refires the module to get the next food, the issue that the module succeed to fire the local script only one time, and then it doesn’t do it anymore.

  3. What solutions have you tried so far? I’ve tried to search up the issue but no one has any similar problem to mine.

Module

function MapsHandler.Main(plr, map)
	local nextFood = game.ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("NextFood")
	local FoodExist = game.ReplicatedStorage:WaitForChild("Values"):WaitForChild("FoodExist")
	local bitting = game.ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("Bitting")
	local Foods = game:GetService("ReplicatedStorage"):WaitForChild("foods"):GetChildren()
	
	local function NewFood()
		local InRound = script.Parent.Parent:WaitForChild("Values"):WaitForChild("Inround")
		local FoodExist = game.ReplicatedStorage:WaitForChild("Values"):WaitForChild("FoodExist")
		local bitting = game.ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("Bitting")
		local Foods = game:GetService("ReplicatedStorage"):WaitForChild("foods"):GetChildren()
		local randomFood = Foods[math.random(1, #Foods)]:Clone()
		local m6d = Instance.new("Motor6D")
		local bites = randomFood:FindFirstChild("Bites")
		randomFood.Parent = plr.Character
		m6d.Parent = randomFood
		randomFood.CFrame = plr.Character:FindFirstChild("HumanoidRootPart").CFrame * CFrame.new(0, 4, -7.5) 
		m6d.Part0 = plr.Character:FindFirstChild("HumanoidRootPart")
		m6d.Part1 = randomFood
			bitting:FireClient(plr, randomFood)
			end
	NewFood()
		
	nextFood.OnServerEvent:Connect(function()
	NewFood()
		end)
end 

Local:

local connection

connection = bitting.OnClientEvent:Connect(function(Food)
	clicker.Enabled = true
  Click.MouseButton1Click:Connect(function()
		local bites = Food:FindFirstChild("Bites")
		Click.Position = UDim2.new(r:NextNumber(0,1),0,r:NextNumber(0,1),0)
		bites.Value = bites.Value - 1
		if Food:FindFirstChild("Bites").Value <= 0 then
			Food:Destroy()
			nextFood:FireServer()
			clicker.Enabled = false
			connection:Disconnect()
		end
		
	end)
end)

And thanks for viewing my issue.

If I read it well, it only works once because in the local script you disconnect the event when it runs, so if you want the event to be run more times you cannot disconnect it. Your local script should look like this:

bitting.OnClientEvent:Connect(function(Food)
	clicker.Enabled = true
  Click.MouseButton1Click:Connect(function()
		local bites = Food:FindFirstChild("Bites")
		Click.Position = UDim2.new(r:NextNumber(0,1),0,r:NextNumber(0,1),0)
		bites.Value = bites.Value - 1
		if Food:FindFirstChild("Bites").Value <= 0 then
			Food:Destroy()
			nextFood:FireServer()
			clicker.Enabled = false
		end
		
	end)
end)

Im in a progress, it works now, but It’s printing out this:

What’s in the line 30? Based on that error, the script is trying to get the value of nil, meaning that the value doesn’t exist

???

nextFood.OnServerEvent:Connect(Food) 

random

This, It’s weird because it’s doing its job and erroring at the same time

if it is throwing an error, it’s because bites cannot be found, maybe try checking if bites exist before executing the event

bitting.OnClientEvent:Connect(function(Food)
	clicker.Enabled = true
	Click.MouseButton1Click:Connect(function()
		local bites = Food:FindFirstChild("Bites")
		Click.Position = UDim2.new(r:NextNumber(0,1),0,r:NextNumber(0,1),0)
		if bites then
			bites.Value = bites.Value - 1
			if Food:FindFirstChild("Bites").Value <= 0 then
				Food:Destroy()
				nextFood:FireServer()
				clicker.Enabled = false
			end
		end
	end)
end)

You must provide the player argument in server events.

nextfood.OnServerEvent:Connect(function(player, Food) end)

Thanks, you saved me time…
It’s the weirdest situation i’ve ever had ngl

It wasn’t working because of that, you gotta add player argument to the function, otherwise it won’t work because “food” will pass the player argument instead of the food argument

@yclii
What kind of code is this?
The code is a mess, There are plenty of things that you should fix with your code as some parts are unnecessary.

Just to Remind you, You are using the Server, you don’t have to wait for Objects as they are already loaded into into the game, I don’t see why you are placing WaitForChild if that wont help what you’re doing.
Plus, your code is all mixed up with other code, try using a thing called Lines to make it easier for you to read.

local rdmFood = Foods[math.random(1, #Foods)]:Clone()
rdmFood.Parent = plr.Character
 -- Line Gap to Separate other Code not Related to this, this makes it easier to find things and read
local m6d = Instance.new("Motor6D")
m6d.Parent = rdmFood
m6d.Part0 = plr.Character:FindFirstChild("HumanoidRootPart")
m6d.Part1 = randomFood

The Server (as already mentioned) as everything loaded in the game, the Client does not, The Client takes time to get everything and Load everything. This is why you use WaitForChild to wait for the Objects Instead of just adding a task.wait() and everything is already there, in this case you are sending Data from the Client to the Server, From looking at this Script, you very much handle it on the Server.

As for your Client code, You should Instead use Activated instead of MouseButton1Click
You should also instead swap out UDim2.new(0,0,0,0) with UDim2.fromScale(0,0) which only manipulates the Scales and not the Offsets, This is basically how UDim2s work:

-- .new will use 4 Arguments to indicate the Scales as following
UDim2.new(XScale, XOffset, YScale, YOffset) -- Manipulates Scale & Offset
-- Below, the functions only take 2 Arguments instead of 4 for a specific scale
UDim2.fromScale(XScale, YScale) -- Manipulates Scale
UDim2.fromOffset(XOffset, YOffset) -- Manipulates Offset

If you are only going to use the Scale, use UDim2.fromScale, if you are going to use Both, use UDim2.new
Another thing, You can easily simplify bites.Value = bites.Value - 1 to just bits.Value -= 1, This is still valid to the code and will still take it as you subracting from a value.

value = value - 1 -- Traditional
value -= 1        -- Simplified

for your FindFirstChild, if you want to Recursively Search through the Descendants, you can set the Second Optional value to true:

Instance:FindFirstChild("Child", true) -- Searches Descendants for the First Pattern

When using FindFirstChild, it wont wait like WaitForChild, instead it will only lookfor the object once and return an Instance or nil.
If you are getting nil, that means the Object:

  1. Doesn’t exist
    The Object may not Exist depending on the ContextLevel, or on the time it was fired.

  2. Is Under a Different name
    It can also be called “Pattern” as FindFirstChild is looking for an Object uner a specific Pattern (The Name Given)

  3. Search Missed the item
    The third one is unlikely to happen just so you know.

So that is why we do if Instance then to check if there instance exists as according the code, we are checking if the Statement is true, if you are checking if the Statement is false, it will be true and allow you to fire the code inside the statement, if you want to check if an Object is nil, you can do if not Instance then to check for that.
If this is only happening for the Client, that means that it may not actually be there on the Client, or hasn’t Loaded in.

So you can basically do this:

if bites and bites.Value <= 0 then

If the first Statement is false, the code wont run, if the statement is true, it will then check the Second Statement to see if its true, Like this for Example:

local Obj -- Automatically Assumed as "nil"
if Obj and Obj.Parent == workspace then
    print"Object Exists."
else
	print"Object Doesnt Exist."
end

Thank you for trying to help, just to let you know my code isn’t this messy though. I just copied and pasted only the necassery lines that could be the issue in the post, thanks for reaching out tho. :smiley:

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