So I'm making my own game. It's almost finished, and anyway, In was talking to my friend about exploits. He said that there are a bunch of anti-exploit scripts. I read about it, and many people say the best way to avoid exploits is to have FE on.
Now, I got a couple of questions.
First of all, what does FE do? I read that it makes so that any changes done by the client stay on the client. So, what would happen if I had a normal brick with FE enabled. Now, if one's client would, via a LocalScript, change that brick's CanCollide to false, how would that work? Wouldn't that one player be able to go through it, but the others not? Isn't that kinda good for exploiters, since others would not be able to follow them? P
What would you have to do to turn a LocalScript into a FE-compatible script? Wouldn't just changing it to a ServerScript and replacing the local player = game.Players.LocalPlayer
with something else do the trick?
Also, does FE affect reading? Like if a script on the client wanted to find out the position of a certain part in the Workspace, could it do so as if FE was off?
Next, how do you work with RemoteEvents and RemoteFunctions? Cause I have totally no idea. How would it look if I want a part created at a certain position when a player presses a key?
Also, my game has quite a lot of explosions and many for loops going on, causing some lag. People told me that since it's on the client, the server should handle it fine and the lag shouldn't be so bad. Will FE affect this?
Lastly, is it worth it? The game I'm making is played by rounds, like MM2. But unlike other games, it doesn't really save anything besides your wins and loses, cause I'm not going to have, like, upgrades or weapon skins or anything. So why would you exploit a game where you have nothing to gain except the experience? So yeah, anything (Answers, comments...) will help.
Thx.
So, what would happen if I had a normal brick with FE enabled. Now, if one's client would, via a LocalScript, change that brick's CanCollide to false, how would that work? Wouldn't that one player be able to go through it, but the others not? Isn't that kinda good for exploiters, since others would not be able to follow them?
You are correct. In that scenario, the server would still have that brick with CanCollide = true. Of interest, if the server then sets CanCollide = false and then back to CanCollide = true, the exploiter's work will be undone. This works for any property that the exploiter makes.
What would you have to do to turn a LocalScript into a FE-compatible script? Wouldn't just changing it to a ServerScript and replacing the local player = game.Players.LocalPlayer with something else do the trick?
Intro to server-client relationship: https://scriptinghelpers.org/guides/server-client-relationship-in-roblox
Essentially, LocalScripts should take care of user input and GUI, while server Scripts should take care of everything else. Usually a server script should do something for all players (which is what you replace local player = game.Players.LocalPlayer
with).
Also, does FE affect reading? No. All commands work exactly the same, even setting the properties - it's just that some of those changes don't get sent to the server. You can use this to your advantage to make Local Parts, or to intentionally only change something for one player.
Whenever you need the client and server to communicate in one way or another, you'll need to use Remote Events and Functions (that's a tutorial, go through it!)
Do note that with FE on, the server cannot access a player's GUI unless it's made by the server (If it was created from StarterGui, it doesn't count), and the client cannot access ServerStorage/ServerScriptService -- they simply don't exist. There are other things that client scripts cannot access, like DataStores.
How would it look if I want a part created at a certain position when a player presses a key?
--LocalScript (ex in StarterGui) local UserInputService = game:GetService("UserInputService") local function onInputBegan(input,gameProcessed) if input.UserInputType == Enum.UserInputType.Keyboard and input.KeyCode == Enum.KeyCode.Q then workspace.AddPart:FireServer() end end UserInputService.InputBegan:connect(onInputBegan) --Put a RemoteEvent named "AddPart" in the workspace (though you can put these in ReplicatedStorage or other places that the client gets, too) --Server script (ex in Workspace) workspace.AddPart.OnServerEvent:Connect(function(player) local p = Instance.new("Part") p.Name = "Part from " .. player.Name p.Position = Vector3.new(0, 100, 0) p.BrickColor = BrickColor.Random() p.Anchored = false p.CanCollide = true p.Parent = workspace end)
Note that even with FilteringEnabled on, there's lots an exploiter can do.
A clever exploiter can use NetworkOwnership to influence any non-Anchored parts that may be near them, even with FE on. You can avoid this by making all non-Anchored parts be owned by the server via SetNetworkOwner.
It is because of Network Ownership that exploiters can do whatever they want with their character (since you always own your character -- this allows for smooth controls and animation), even in FE. As you suggest, exploiters can walk through bricks. They can also cause their character to jump in midair, move very quickly, or teleport.
Fortunately you can only influence CFrame (and probably the Velocity properties) - you can't change BrickColor, for instance. You may be able to convince the server to delete the part by throwing it into the void (ie giving it a Position.Y of -1000).
Also, if you have any RemoteEvents/RemoteFunctions, you should assume that the exploiters know how to use them and can/will send any values they like. https://scriptinghelpers.org/guides/how-to-use-remoteevents-properly goes over this idea.
You can test this all for yourself -- go into a new/blank place, turn workspace.FilteringEnabled on, Start Server with 1 player, into the server add an unanchored brick (and make sure it isn't connected to the baseplate -- try moving it into the air), and then go into the client and see what changes you can make to the part. If the change is visible to the server, then an exploiter can make that change too.
Anti-exploit scripts are therefore still necessary, even with FE. Such scripts can try to do any or all of the following:
ChildRemoved
or AncestryChanged
, it will run before the exploiter has the chance to remove the rest of the scripts (even if they're using a loop that doesn't yield).Also, my game has quite a lot of explosions and many for loops going on, causing some lag. People told me that since it's on the client, the server should handle it fine and the lag shouldn't be so bad. Will FE affect this?
There are multiple places for lag:
FE being on doesn't change this reality, though it may force you to run more stuff on the server. If you have lots of for loops running and lagging the client, moving those scripts to the server may help -- Roblox's servers are usually fairly powerful.
Lastly, is it worth it? It depends on how successful you want your game. For some, exploiting is its own reward. Destroying servers and making them unplayable is "cool"; it's "breaking the system". I have seen exploiters wipe servers before, when they didn't have FilteringEnabled, or continuously kill everyone's characters, or make themselves invincible in a fighting game, etc. Even with FilteringEnabled, as I've described above, some people will try to exploit to gain an advantage over others -- even if they don't get anything permanent out of it. (Some will exploit just for the fun of it - to see what they can make your game do.)
So, if your game becomes popular, do not doubt for a second that people will exploit it -- especially if it's got FilteringEnabled off. Whether it's worth it for you to prevent that is up to you.
Without filtering enabled, if an exploiter inserts a part, every other client will see that part, because it gets replicated over to the other clients. (This counts for every instance, not just parts!)
If you have filtering enabled turned on, every client will only be able to interact with the server through Remote Events and Functions. If an exploiter would then insert a part, only they will able to see and interact with it.
With FE turned on, you will need to use Remote Events and Functions to communicate from client to client. For instance
-- Client --Fire "A String" to the server game.ReplicatedStorage.RemoteEvent:FireServer("A String") -- Server --Event callback function for the Remote Event. OnServerEvent will always have it's first argument be the Player that fired the event. game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(PlayerFrom,Argument) --Fire "A String" to all the clients. Some kind of Chat. game.ReplicatedStorage.RemoteEvent:FireAllClients(Argument) end)
If you have any other questions feel free to leave a comment, I log on SH daily.