What's a good way to make a FFA gamemode?

I see, thanks for your input. I’m gonna go look some more and just do it from the client to the server and encrypt it somehow.

1 Like

The client has access to everything that MUST be on the client. Map and local scripts are examples of things that are downloaded by the client. Local scripts can be modified in any way, shape, or form by the client, because the client has ownership of them. This is by no means exploit proof.

All of this code should be from the server side to prevent from exploits. Remote events are not necessary.

Okay, that’s what I assumed. Could you still exploit the server as he said?

Intresting. I have never seen a exploit that changes the clients script. How does one exploiter change a local script and how would it be noticable and run in real time

As I said above, the user can do whatever they want with local scripts. As the name implies, they are local scripts that are run on the client. This makes them vulnerable, because the client can do whatever they want with them, because they are running on the user’s computer.

1 Like

And I am aware of some of that. I know a exploiter can easily delete a local script, disable it, move it ect. However. again, I haven’t seen editing of a script done before on the client. Below I have added to links to 2 different dev forums. It seems like well, again yes, things can be done. The act of editing the local script cannot be done. Reading the script can, as well as destorying it, but again, I have never seen editing of a local script
https://devforum.roblox.com/t/can-exploiters-edit-local-scripts/1323544
https://devforum.roblox.com/t/can-exploiters-interfere-and-edit-a-localscript-etc/876235

In this case, the Values are store in the script, not in a outside value. The only way a hacker could exploit is by editing the live script or cloning said code into a new script, which could be stopped with a client anti-cheat

That makes sense, but there is no point when you could run it on the server and then add exploit detection there too. Client-side would just give the player the possibility to exploit the system.

And that may be best for you. For me It would seem to be easier to Client side as I have more experience with dealing with local scripts and protecting them. There really isn’t a wrong or right here. It’s whatever works for you and you have a plan to store data

A better way to visualize this problem is to not ask the question

“why should an exploiter be able to edit a local script?”,
but to rather ask the question,
“why shouldn’t an exploiter be able to edit a local script?”
There is no reason that they should not be able to modify a script that is running on the user’s device.

Also, I find it funny that one of the threads that you linked had a solution that said that it WAS possible.

Do you have any tips on how I could make my FFA game mode on the server? What functions should I connect it to so it can run forever and always check?

any type of loops would cause lag in your game

its a stupid idea to even mention making something like this on the client because all the exploiter can do is change their kills and they won

use .changed events for each player who is already in the game (loop through players) and for ones who join (playeradded)

local Players = game:GetService("Players")

function Check(plr)
    if plr.leaderstats.Kills.Value >= requiredKills then
        -- remote
   end
end

for i, v in pairs(Players:GetPlayers()) do
    v:WaitForChild("leaderstats"):WaitForChild("Kills").Changed:Connect(function() Check(v) end)
end

Players.PlayerAdded:Connect(function(plr)
    v:WaitForChild("leaderstats"):WaitForChild("Kills").Changed:Connect(function() Check(v) end)
end)

I would recommend hooking a dictionary with connections linked to the player’s username (the connection being the kills value changed) and then you can remove the connection by finding it in the dictionary when a player is removed. That would look something like this:

local Players = game:GetService("Players")

local ConnectionsHolder = {}

local function Check()
    -- Check stats here
end

Players.PlayerAdded:Connect(function(Player)
    -- Find the kills value (this code assumes there is a variable linked to it named Kills)
    local Connection = Kills:GetPropertyChangedSignal("Value"):Connect(Check)

    ConnectionsHolder[Player.UserId] = Connection
end)

Players.PlayerRemoving:Connect(function(Player)
    if typeof(ConnectionsHolder[Player.UserId]) == "RBXScriptConnection" then
        ConnectionsHolder[Player.UserId]:Disconnect()
        ConnectionsHolder[Player.UserId] = nil
    end
end)

Edit: I just noticed my code was not correct so I modified my post

@TestAccount563344 @OfficialPogCat heres an explanation on exploiting something like this

lets say the game had a local script that manages the kills. this script has a local variable to count kills and tracks kills by checking deaths (bla boa leaderstats stuff). no the exploiter cant just edit this script roblox loads script once and only once (unless its a module script but then again, exploiters cant edit scripts). once the kills reach a certain amount it called a remote event

heres how an exploiter instantly bypasses that
RemoteEventLocation:FireServer()
exploiters can read scripts (not edit)

so your first thought is to try to put a private key passed into the event. this wouldnt work because again, exploiters can read scripts

exploiter reading the script:

local key = "secureKey"
remoteeventlocation:FireServer(key)

exploiter copying the key: remoteeventlocation:FireServer("secureKey")

now your second thought may be to get the key from a module script or firing remote to the server.
this would not work either since the exploiter could just require the same module script or fire the same remote to get it.

your third thought may be an expanded version of the second one. you secure the remote to the server to get the key by making it one time use (table the stores players who called the remote). this wouldnt work either due to something called RemoteSpy. this exploit lets the exploiters view all remote events being called in and out and what their arguments are

in short. tracking kills on the client is a terrible idea and should stay on the server

no connection handling is needed here because the player object gets destroyed after leaving

From what I remember, the changed connection for the value will remain. Correct me if I’m wrong. Also, exploiters can sort of edit scripts by copying & changing the code and replacing the old script. :confused:

not really editing it basically just creating/running a new script. those extra steps they could of just used the inapp script runner

and all connections binded to an object and its descendants are disconnected after it gets destroyed

Okay, thank you for the explanation! I don’t want to be spreading any misinformation. :slight_smile:

Players.PlayerAdded:Connect(function(plr)
    v:WaitForChild("leaderstats"):WaitForChild("Kills").Changed:Connect(function() Check(v) end)
end)
--  ^ this v is undefined

just copied it over replace ‘v’ with ‘plr’

Oh okay, thank you I appreciate it that works. How would I go about resetting all players kills? I looked into it a bunch and couldn’t find anything. My guess would be to loop through players and then reset each one but I don’t know.