I’m currently attempting to protect a GUI local script from map stealing by putting it in serverscriptservice and then using a separate local script to detect which button is pressed so it can fire the buttons name to the main local script. Is there a better way to do this than having the first local script just firing the server to a server script then back to the main GUI’s local script?
an exploiter can copy any Local scripts, Module Scripts and any map from Workspace or Replicated Storage. You can’t do anything to stop it. They can copy entire games.
The only things that can’t be stolen are items not replicated to the client. You’re setting yourself up for failure and shooting yourself in the foot by trying to complexify your code for something that can be inherently stolen. Without the map replicated or visible to the client, they can’t render or activate any pipelines on it, therefore can’t play on it.
The better way to do this is to not do it at all.
I thought that they couldnt take scripts from serverscriptservice?
They can’t from SSS, SS and some spaces. They can’t get Server Scripts.
So what would be the best way to protect my map and its scripts?
Can they take local scripts from serverscriptservice?
No. Players can’t acces SSS or SS
You don’t. Your map needs to be replicated to the client in order for it to have any meaning to a player (rendering, physics, so on) and anything that’s replicated to a client can be stolen as well.
Your scripts are fine in any location because their sources are not replicated to the client. ModuleScripts are only secure if placed in a server container, otherwise their sources do replicate by nature of being able to be required by both environments. LocalScripts are inherently browsable and can have their sources stolen.
If you parent a LocalScript to ServerScriptService locally, it will still be visible to exploiters. ServerScriptService and ServerStorage just don’t replicate from the server to the client. Either way, the LocalScript won’t be running there so there’s no point in doing so. For the code to run on the client’s machine, it has to be on their machine.
So anyone could easily just go into my game and take my local scripts and I cannot do anything about it, because theres nothing protecting it.
Yes, that’s right. Roblox has done what they can from their end but again, their machine, their control.
Here’s a resource thread that may be of interest to you:
You can’t protect Module Scripts and Local Scripts.
Yes you can, only if:
It’s inaccurate to say you can’t period, but if you don’t place them in a container that doesn’t replicate to the client, then yes, it’s not secure, the client can see that and needs to to run it at all.
Moving the script to ServerScriptService on the client side will simply make said script show up in ServerScriptService. Moving it on the server, however, will actually cause the client to delete the LocalScript. The issue is, the script is still in memory, it must be for its code to run, so it can still be extracted. Most exploits offer the ability to access “nil instances” aka instances that are deleted/parented to nil. Some instances won’t get cleaned up, for example, running LocalScripts.
While its not possible to protect code from being decompiled and stolen, it is, however, possible to make their contents harder to read. Exploits are only recently coming out with Luau decompilers, and due to luau’s lack of local variable information, the names of the variables are automatically generated based on the executing code (e.g. Instance.new, or WaitForChild calls are used to produce a better, more readable name for the variable). Strings are also still decompilable (If they weren’t it’d be impossible for LocalScripts to use strings at all. They just have to be usable)
Some things that won’t change decompiled code: Whitespace (e.g. new lines, extra spaces, etc), comments (these aren’t saved in bytecode at all, you can include as many comments as you want), variable names
NOTE ABOUT FUNCTIONS: Functions declared using function name()
or local function name()
DO store their names. You can most likely get around this by using local name = function()
or name = function()
(storing them in a variable). This is for debug purposes since it’d be extremely difficult to read stack traces without them.
Personally, I don’t spend much time trying to obfuscate, protect, etc my local code. I simply treat local code as if anyone can read and edit it, since this is pretty much exactly the case.
I made an admin panel local script which detects If admins join. Then made a script that moves the GUI from server storage to starterGui. then the local script destroys it self. After than another local script checks if he is an admin then makes the gui enabled for him.
Instead of doing this you should have server code store an administrator GUI, and then the server simply gives the client the GUI. Then in your server code you’d just need to check if the user making requests through a remote within the GUI is an administrator. If you aren’t checking if the user is an admin on the server, your code will be exploitable since you’re relying on client behaviour to be secure, which you just can’t do.
Yeah you are right thanks. 30 chars