Security can be a large concern in Roblox. While most of the community plays by the rules, there are those who seek to exploit games: corrupting data stores, stealing player points, injecting models into games, the list goes on. There are ways you can keep your games more secure though. Below are a few methods to help keep your games safer.
A sound way to prevent exploits is to turn off Experimental Mode. This setting is used to indicate that a game is in an experimental and potentially unstable state. In this mode client code can make arbitrary changes to the game world. This can be useful when prototyping or experimenting, but is undesireable and unrecommended when a game is ready for the public.
This Experimental Mode is turned off, the engine prevents object replication from the Client (the machine the player is running on). This means that if the Client tries to add parts or manipulate the properties of existing parts, the change will not propagate to the server or other players. Any calls from a Local Script that attempts to do this with Experimental Mode disabled will fail.
In general, this relationship between the server and client works well for most games. The server is responsible for maintaining the game world while the client is responsible for rendering and getting user input. There is certainly communication between the two, but both client and server have their respective tasks to perform.
Turning off Experimental Mode will have the side effect of breaking a fair number of older vehicles and gear, as these often directly changed the properties or created instances in the Workspace. That said, most of these should be fixable by communicating between the client and server with Remote Events or Remote Functions.
Another thing that can keep your game secure is to keep loadstrings disabled. These are disabled by default, so do not turn it on unless you have a very good reason to. This setting can be found in ServerScriptService under LoadStringEnabled.
Loadstring is a very interesting lua function that allows arbitrary and dynamic code to be executed at runtime. This can be very powerful, but since it can run literally anything it can be very dangerous. With loadstring disabled, any Scripts on the server that use loadstring will throw an exception when loadstring is called. Loadstring cannot be used in Local Scripts on the client. This feature was disabled, and will error when usage is attempted.
Roblox has a wealth of already made Models and plugins to make game development easier. That said, it is important to exercise caution when downloading from the Roblox catalog, even for popular items.
When using a model, check it for any scripts. If it does, go through the script and try to see if it does anything odd, such as adding parts, accessing services it shouldn't etc. If you see code that you do not understand, take this opportunity to learn. Roblox has a very active community that can be very helpful. Just keep in mind when asking about code try to be as specific as you can. Posting 50 lines of code and asking what it does is not likely to produce an answer, but if you see a short segment, perhaps 5 lines that you want to know more about, just post those.
Even if you are reasonably sure that the code works fine, be mindful when testing your game, both in Studio and when it is published on Roblox. If you see odd behaviour, try removing some recently added models or plugins to see if the problem stays or goes away.
In secure modes (i.e. Experimental Mode disabled), Local Scripts have more restrictions on what they are allowed to do. Some old scripts may break because they try to call functions they no longer have access to. If you need to fix these scripts, or you are writing new scripts and need to trigger server specific functions in a Local Script, use a RemoteEvent or RemoteFunction.
For example, lets take a simple local script that changes the color of a Part in our game called ColorBrick when the user clicks on it:
-- Local Script : this script will break with Experimental Mode off! local clickDetector = Instance.new("ClickDetector") clickDetector.Parent = game.Workspace.ColorBrick clickDetector.MouseClick:connect(function() game.Workspace.ColorBrick.BrickColor = BrickColor.Red() end)
If Experimental Mode is turned off, the part will only turn red for the player who clicked it; everyone else would see not change whatsoever. To fix this, it is a simple matter to use a RemoteEvent to trigger the color change. First change the local script to be:
-- Local Script : This script will work with the Server Script below, even with Experimental Mode turned off. local clickDetector = Instance.new("ClickDetector") clickDetector.Parent = game.Workspace.ColorBrick clickDetector.MouseClick:connect(function() game.Workspace.MyEvent:FireServer() end)
Then, create a new server script to handle the event and change the color of the part:
-- New Server Script local event = Instance.new("RemoteEvent") event.Name = "MyEvent" event.Parent = game.Workspace event.OnServerEvent:connect(function() game.Workspace.ColorBrick.BrickColor = BrickColor.Red() end)
With Remote Events like above (or Remote Functions if you need to return a value) you should be able to fix any Local Script that breaks due to Experimental Mode being turned off. This technique also works for when one needs to call server specific functions from the client. For instance, using InsertService from a Local Script does not allow importing assets that other people created. If that is important for your game, simply run the InsertService calls on the server, and connect them to the client with a RemoteEvent like the above example.