it’s because when receiving an OnServerEvent
from a Client
the Player
object automatically gets parsed to the Event
like so:
RemoteEvent.OnServerEvent:Connect(function(player) -- insert other arguments here
print(player) -- prints the player who fired the Remote in the first place
end)
(Server Script) FIX:
this version of your code is safe from any exploiters by using ServerSide Cooldown management.
local part = game.Workspace:FindFirstChild("Part")
local Ability = game.ReplicatedStorage.Ability
local Cooldown = false
local cooldownTime = 3 -- change this to how long you want the cooldown
Ability.OnServerEvent:Connect(function(player, ability)
if Cooldown == false then
Cooldown = true
part.Color = Color3.new(ability)
task.wait(cooldownTime)
Cooldown = false
end
end)
Recommended:
If using Server Side cooldowns I recommend reading this part which shows how to make independent server cooldowns for each player as using the basic “Cooldown” or “Debounce” variable will cause 1 player to be able to fire the code every time the cooldown variable is false rather than each player being able without worrying about when another person last fired it (hence the word independent)
Local Script
local part = game.Workspace:FindFirstChild("Part")
local Ability = game.ReplicatedStorage.Ability
local UserInputService = game:GetService("UserInputService")
local function RandomColor() -- a simple function that returns a random RGB-based color value
local r, g, b = math.random(1, 255), math.random(1, 255), math.random(1, 255)
return r, g, b
end
UserInputService.InputBegan:Connect(function(input, isTyping) -- basic UIS stuff
if isTyping then return end
if input.KeyCode == Enum.KeyCode.One then
local r, g, b = RandomColor()
print(r, g, b)
Ability:FireServer(Color3.fromRGB(r, g, b)) -- convert the color value into RGB format then send it to the server
end
end)
Server Script
local part = game.Workspace:FindFirstChild("Part")
local Ability = game.ReplicatedStorage.Ability
local cooldownTime = 3 -- change this to how long you want the cooldown
local onCooldown = {} -- a table that holds the players that are on cooldown
Ability.OnServerEvent:Connect(function(player, ability)
if not table.find(onCooldown, player) then -- if the player isn't on cooldown...
table.insert(onCooldown, player) -- put them on cooldown here
part.Color = ability -- change the color of the part to whatever the random value generated
task.wait(cooldownTime) -- wait cooldown time
table.remove(onCooldown, table.find(onCooldown, player)) -- take the player off cooldown
else
warn(player, "is on cooldown!") -- if the player tries to fire this code, this will print in the output
end
end)
This is a more advanced but necessary way of handling Server Sided cooldowns and although it can seem like a bit much effort and confusing for beginners it is vital when making a secure and almost unexploitable game!
I hope this helped!