Hello, I am trying to make a script where when you click (or hold) a text button you will get coins, and holding it can get you coins up to 20x per second depending on ur upgrades. I just became aware you can only use remoteevents 20x per second for the entire server. How can I work around this while maintaining security without a remote event?
Maybe you could count the amount of clicks that you do in a second or two and then at the end of said time fire the remote event, cause unless you want exploiters to break you game you are gonna need to use remote events sadly :<
Anyhow this should work in theory dont quote me on it, this is just my brain runnin.
Best of luck!
The limit definitely isn’t 20/second.
You can handle the logic locally and periodically update the server with the total coins earned.
This is how it would work:
-
Local Script (Client-side):
- Track clicks or holding on the text button.
- Accumulate coins locally.
- Periodically send the accumulated coins to the server using RemoteEvent, but ensure it doesn’t exceed the requests per second limit.
-
Server Script:
- Receive the total coins from the client at regular intervals.
- Update the player’s total coins securely.
With this logic, how would I know if it was a max 20x per second or however much the user is allowed on the server end? Also since there will probably be a gamepass that doubles the amount per click
Upgrades and statistics should be held on the server side to be safe from exploiters. RemoteEvent is required when communicating between server and client.
Possible server-side solution
local mySampleUserUpgradesTable = {} -- Empty. This is example. Don't get a long name like this one
local function userClick(player) -- Connect this to Remote Event OnServerEvent
if mySampleUserUpgradesTable[player.UserId] then
givePlayerCoins(player, mySampleUserUpgradesTable[player.UserId][ClicksAllowed])
end
end
You don’t need to spam Remote Events for every each click with multipliers. If you need specific help with understanding this, let me know.
Where did you hear about that limit? I haven’t heard of such a limit before; the closest thing I can think of would be that there’s a limit for the maximum amount of data you can send through per call, but that’s completely separate from the number of times a RemoteEvent
is called per second.
If there was such a limit for maximum calls per second on a server-wide scale, that would be important enough to be documented on the Remote Events and Callbacks guide on the Roblox Creator Documentation site.
Whether or not a limit of 20 calls per second exists can be tested by calling RemoteEvent:FireServer()
every frame; in this example, it doesn’t stop firing the RemoteEvent
within each second after the 20th call:
Example Client-sided code
-- Example code for a LocalScript in StarterPlayerScripts
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
---
local totalTimeElapsed = 0
local numberOfRemoteEventCalls = 0
local desiredWaitTime = 1
local currentWaitTime = 0
local connection
connection = RunService.RenderStepped:Connect(function(deltaTime)
totalTimeElapsed += deltaTime
currentWaitTime += deltaTime
numberOfRemoteEventCalls += 1
print(numberOfRemoteEventCalls)
RemoteEvent:FireServer(numberOfRemoteEventCalls)
if currentWaitTime > desiredWaitTime then
currentWaitTime -= desiredWaitTime
numberOfRemoteEventCalls = 0
warn("1 second has passed")
end
if totalTimeElapsed >= 10 then
warn("Test has concluded. Please review the Output")
connection:Disconnect()
end
end)
Example Server-sided code
-- Example code for a Server Script in the ServerScriptService
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
RemoteEvent.OnServerEvent:Connect(function(player, numberOfRemoteEventCalls)
print("OnServerEvent: "..tostring(numberOfRemoteEventCalls))
end)
I think I’m not explaining it correctly sorry, so the user can click the button and gain one coin; or they can hold the button and gain 2 coins per second (one coin everfy half second). But that coins per second could be upgraded to 20. this is what im having issues with si like how do i impliment that without remote events since the user could hold for a half a seocnd for exmaple, or i could do simething with every second i update on server until release
im lost
I tested this and it averaged at over 2000 calls/sec. I binded renderstepped and heartbeat to a function that fires a remoteevent.
- Create a remote function in ServerScriptService to handle coin calculations based on player upgrades.
- Use a LocalScript to capture button clicks or mouse holds and calculate coins to add.
- Send a request to the remote function with the calculated coins.
- Server checks for upgrades, applies them, and updates the player’s coin count.
Why use a remote function if you’re not returning anything? Remote events would have to be faster.
No. I understood what you said perfectly. The method you are trying to wrap is just inefficient and causes issues.
Client and Server communication is NOT POSSIBLE without RemoteEvents / RemoteFunctions (which is almost the same as RemoteEvents)
My response implies that you are supposed to store the player’s calculated gains (Default coin game * multipliers) on the server and have the player fire the RemoteEvent per click (just so you don’t have to repeat firing the RemoteEvent every click for the upgrades). This way, when they hold, the client fires RemoteEvent only twice per second and not 29737292 depending on the upgrades.
As @nvthane said, it wouldn’t be possible to communicate between server/client without using RemoveEvents/Functions. With this in mind, the most secure & efficient way to do this is to have 2 RemoteEvents, one for the MouseButtonDown and the other for the MouseButtonUp. When a player presses down the textbutton, fire the MouseButtonDown RemoveEvent and when the textbutton is released, fire the MouseButtonUp RemoveEvent. On the server, when each RemoteEvent has been fired, store a time in which they were done so.
Example
-- LocalScript (in StarterPlayerScripts)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local PlayerGui = Players.LocalPlayer.PlayerGui
local TextButton = -- the location of your textbutton
local MouseDownEvent = ReplicatedStorage.MouseDownEvent
local MouseReleaseEvent = ReplicatedStorage.MouseReleaseEvent
TextButton.MouseButton1Down:Connect(function()
MouseDownEvent:FireServer()
end)
TextButton.MouseButton1Up:Connect(function()
MouseReleaseEvent:FireServer()
end)
-- ServerScript (in ServerScriptService)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local MouseDownEvent = ReplicatedStorage.MouseDownEvent
local MouseReleaseEvent = ReplicatedStorage.MouseReleaseEvent
local down = {} -- use a table to store each player's time
local release = {}
MouseDownEvent.OnServerEvent:Connect(function(player)
-- tick(), time in which the textbutton was pressed
down[player] = tick() -- assigns each player a time, player acts as a key for the table
end)
MouseReleaseEvent.OnServerEvent:Connect(function(player)
release = tick()
delta = release - down
-- the average click is about 85ms or 0.085 seconds so 1 click can be detected as:
if delta < 0.085 then -- adjust to your preference
print("1 click has been made")
end
print("Button held for:", delta, "seconds!")
end)
Using the delta, you can do your math to calculate how many coins the player receives depending on their upgrades.
Resources
python - How much time should the mouse left button be held? - Stack Overflow (at bottom of page)
You could just use a server script to handle the making your coins go up whenever you click the button. While it’s not as optimal as just using a remote event it is more secure and you can still script most UI in a server script.
game.Players.PlayerAdded:Connect(function(player)
local button = player:WaitForChild('PlayerGui'):WaitForChild('ScreenGui'):WaitForChild('TextButton')
button.MouseButton1Click:Connect(function()
print('hi')
end)
end)
You can do that by tracking the number of clicks per second on the client-side and send this information to the server along with the coin gain request and then on the server-side, ensure the requests don’t exceed the maximum allowed rate (20x per second). Also, handle any multipliers from game passes.
Local Script Example (Client-side):
local button = script.Parent
local player = game.Players.LocalPlayer
local coinsEarned = 0
local clickCount = 0
local maxClicksPerSecond = 20 -- The maximum allowed clicks per second
local coinIncrement = 1 -- Adjust based on upgrades
local interval = 0.1 -- 10 times per second
-- Assuming the player has a gamepass, modify coin increment if applicable
local hasGamepass = -- logic to check if player has the gamepass
if hasGamepass then
coinIncrement = coinIncrement * 2
end
local function earnCoins()
if clickCount >= maxClicksPerSecond then return end
clickCount = clickCount + 1
coinsEarned = coinsEarned + coinIncrement
end
button.MouseButton1Down:Connect(function()
while button:IsPressed() do
earnCoins()
end
end)
-- Reset the click count every second
game:GetService("RunService").Stepped:Connect(function(time, deltaTime)
if deltaTime >= 1 then
clickCount = 0
end
end)
-- Periodically send accumulated coins to server
game:GetService("RunService").RenderStepped:Connect(function()
if coinsEarned > 0 then
game.ReplicatedStorage.CoinEvent:FireServer(coinsEarned, clickCount)
coinsEarned = 0
end
end)
Server Script Example:
local CoinEvent = Instance.new("RemoteEvent")
CoinEvent.Name = "CoinEvent"
CoinEvent.Parent = game.ReplicatedStorage
local maxClicksPerSecond = 20
CoinEvent.OnServerEvent:Connect(function(player, coins, clickCount)
-- Validate clicks per second
if clickCount > maxClicksPerSecond then
-- Optionally handle violation (e.g., warn the player, log the incident)
return
end
-- Validate and add coins to player
if typeof(coins) == "number" and coins > 0 then
local leaderstats = player:FindFirstChild("leaderstats")
if leaderstats then
local coinsStat = leaderstats:FindFirstChild("Coins")
if coinsStat then
coinsStat.Value = coinsStat.Value + coins
end
end
end
end)
Explanation:
-
Local Script:
- Tracks the number of clicks per second (
clickCount
) and ensures it doesn’t exceed the limit (maxClicksPerSecond
). - Adjusts the coin increment based on whether the player has a gamepass.
- Resets the
clickCount
every second. - Sends the accumulated coins and
clickCount
to the server periodically.
- Tracks the number of clicks per second (
-
Server Script:
- Receives the coins and
clickCount
. - Validates that the
clickCount
does not exceedmaxClicksPerSecond
. - Adds the coins to the player’s total if validation passes.
- Receives the coins and
you don’t need to do any of this? he wants it without a remote so he could just use a server script to make the UI work and he could detect how many times the button is clicked in a certain time frame. also this is some of the worst code ive ever seen never cook again its so exploitable.
Smart man, this is a clever solution thank you!
how is this smart he gave u the complete opposite answer to your question when theres an answer which fits your question perfectly??? + its not even “clever” its just tick its common sense when you want to check how often a remote is being fired… + he didn’t even notice the dumb error in his script he’s doing tick() - table instead of tick() - table[player.Name]
I highly suggest you gain coins on click with Remote Events
. If you do it without Remote Events
, your game is easily exploitable and exploiters will be able to edit your LocalScript
and give themselves a ridiculous number of coins.
Yeah, and how secure would the game be without remote events?