You know exploiters have access to the debug library, right? https://www.lua.org/manual/5.1/manual.html#lua_getupvalue
A “secret” code is meaningless if an exploiter can just find it by, for example, hooking any function in that script and getting its upvalues.
This is why developers recommend to not trust the client.
Even if you managed to make something hard to crack, you’re fighting not against one exploiter, but against thousands, if not more. It will generally get bypassed in less time than it took you to create the anticheat (or at least fast enough that it’s not worth the effort).
It’s simply not cost-effective to implement client-sided anticheats unless you have people on your team whose sole purpose is doing that.
You’re right; exploiters can access the debug library in Lua. However, the “secret” code in the script serves as a layer of security. While it’s not foolproof, it adds a barrier that exploiters need to overcome. The script aims to make exploiting more challenging, not impossible.
The script is just one part of a multi-layered anti-exploit strategy. While it’s true that some exploiters are persistent, implementing client-side anti-cheat measures is still worthwhile. It deters a significant number of potential exploiters and can buy time for server-side anti-cheat mechanisms to kick in.
In the end, a robust anti-exploit system involves a combination of client and server-side measures. While it may not stop all exploiters, it can significantly reduce the number of successful exploits and improve the overall gaming experience for legitimate players.
Using a repeat loop with wait in the script to find the “Security” RemoteFunction was a deliberate choice. While we could have used :WaitForChild() for a quicker wait, we decided on the repeat loop to make sure the client consistently checks for the RemoteFunction’s existence. This way, even if the RemoteFunction’s name changes or it’s created later, the client script won’t miss it. It’s about being adaptable to changes in the server’s setup.
Now, about creating the RemoteFunction dynamically with Instance.new(), you’re right that :WaitForChild() is usually recommended to avoid latency issues. However, in this specific script, our main concern was ensuring that the client keeps searching for the RemoteFunction. While latency is important, maintaining a reliable reference to the RemoteFunction was crucial in this situation.
You’ve raised a valid point regarding potential exploiters trying to mess with client-side code and using tools like “RemoteSpy” to intercept secret keys. It’s important to note that this script isn’t a complete anti-exploit solution. It acts as a foundational layer of defense. To enhance security, we’d need additional layers of protection and obfuscation to make it harder for exploiters to manipulate the system.
You might be confused, since I’m not American and my native language is not English, I use DeepL to communicate or to correct any grammatical mistakes I make from time to time.
And yes, I know RemoteSpy, but as I said 3 times here, the script I sent you is just a starting point.
Thank you for sharing your expertise. While this script isn’t foolproof, it’s a starting point for those looking to enhance security.
I took a look at your thread, see if you are now satisfied:
LocalScript:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction
repeat
remoteFunction = ReplicatedStorage:FindFirstChild("Security")
wait(0.7)
until remoteFunction
local inputCode = "code1"
local checkInterval = 5
spawn(function()
while true do
wait(checkInterval)
local success, result = pcall(function()
return remoteFunction:InvokeServer(inputCode)
end)
if success then
if type(result) == "string" and result == "code2" then
print("Received code2 from the server.")
end
end
end
end)
Script 2 (Server):
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = Instance.new("RemoteFunction")
remoteFunction.Name = "Security"
remoteFunction.Parent = ReplicatedStorage
local secretCode = "code1"
local playerRequestTimes = {}
local maxRequestInterval = 5
remoteFunction.OnServerInvoke = function(player, inputCode)
local currentTime = tick()
local lastRequestTime = playerRequestTimes[player]
if lastRequestTime and (currentTime - lastRequestTime) < maxRequestInterval then
return false
end
playerRequestTimes[player] = currentTime
if type(inputCode) == "string" and inputCode == secretCode then
return "code2"
else
return false
end
end
What you could do though is use encryption (ex AES-CBC) and StepNumbers, that would be the very least in terms of security,
But if you want to take it a step further, make a client anticheat in addition to your server one and add Anti HookMetaMethod, Overflow Checks, and even CoreGui checks which are all easy to make (from my perspective)
Here you are misleading new developers by using ChatGPT to get easy likes, however what you are actually doing is making yourself look inexperienced and making other’s game security weaker and easier to attack for exploiters.
I was talking about handshakes, + you are still not using :WaitForChild and you are still not using the task library which is way more optimized than spawn and wait.
This is an unoptimized method, please use :WaitForChild when possible as it is written in C++ (not lua) and is essentially the same thing as you are doing, except it will be way faster.
This will never work because the client can see all code so the client can see the “Secret Code”, the only way to establish secure connections between the server and client is to make a algorithm that is not the same on the client and server which will get the same awnser defining the server as the server, i don’t know exactly how works so this might be all wrong however it is the basics. It is however pointless
I remember making something like this when I was new to programming in 2018. It certainly doesn’t prevent exploiters, because they can always just intercept the code with their own substitute script in place of the clientside script you expect the user to have, but it is a fun starting place to learn from.
The most you could say about these types of systems is that it makes it a little more difficult for exploiters to mess with your game. Certainly the vast majority of exploiters wouldn’t even know where to start, but the problem is that it takes only one smart person to make the counter-counter-exploit and then all the newbie hackers can just use that one.
While the criticism in these replies can be uncharitable and discouraging, I agree that this does not belong under #resources:community-resources only because it could lead less experienced developers to using a tool which does not work as advertised. Perhaps #help-and-feedback:creations-feedback could be an appropriate place for more balanced feedback.
The only way to stop exploiters effectively is by making no client to server communication where the client makes the server believe something the client says is true
I don’t believe I’m a great programmer. I’ve been programming in Luau for just under a year. When I sent this, I really envisioned (and still do) that this is better than simply leaving the scripts completely unprotected. That’s why I said:
Of course, this is just one approach.
But anyway, no one seemed to understand that it was just an attempt to improve script security. The world needs people like you, and thank you for the suggestion. If I create another script like this, I can post it in #help-and-feedback:creations-feedback.