I’m trying to create an FFA system that triggers a win event. I want the kill system to not have a time limit but, only connect a function when the 1 player reaches a certain value and determines them as the winner. Lastly, SERVER SIDED!
I don’t really know where to start! My first idea would’ve been to connect to a while wait() do OR kills.Value:Changed(connect(function)
local function WinEvent()
-- WIN SEQUENCE
-- DETERMINE WINNER HERE
end
while wait() do
if Kills.Value == 25 then
WinEvent()
end
end
OR
local function WinEvent()
-- Win sequence.
end
Kills.Value.Changed:Connect(function)
if Kills.Value == 25 then
WinEvent()
else
end
end
I really don’t know how to start this and I also feel something like this could be easily exploited.
Any help is greatly appreciated as I’m currently stuck. Thanks!
My first thought is to have a value on the client side in a local script. And kills would be added to that. And when the client side has enough kills, It fires the server. Something like this
local Kills = 0
local HasSomeoneWon = false
repeat wait() until Kills >= 25 or HasSomeoneWon == true
if Kills >= 25 then
game.ReplicatedStorage.WinEvent:FireServer()
Kills = 0
else
Kills = 0
end
Again, this is not at all done or scripted, but this is maybe how I would start off, unless someone else has a better idea. I don’t make really FFA gamemode/games, but I wish you luck!
Thanks for the reply! But, I don’t want to do it on the client because that would allow exploiters to change their own values and trigger the win event.
The Kills Value I have left in the script only, and not as a Int value. So I don’t think exploiters can change that. Secondly, the trigger of the event could be prevented I think By having a code to the event that the scripts know, and no one else knows. On the server it would look something like this
(I am newer to keeping events safe, I think this is how you would do it)
game.ReplicatedStorage.WinEvent.OnServerEvent:Connect(function(PlayerWhoWon, IsItFromScript)
if IsItFromScript == "" then --Whatever you set it too
end
end)
You very well can do it in both. My first idea is to hook up the client and server. But you can do it both ways. The problem that went in my head is keeping that value safe if on server side, and well not many, There are server exploits to change server values if you use int values. If that problem is fixed, Then it doesn’t really matter.
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.
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.
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.
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
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