For events that happen client side how do I securely store the results on the server (such as award points)?

In my game (which is an obby) the player is awarded points based on things they touch on the map. So If they touch a bounus ring they get points.

For optimization reasons, nothing is happening on the server side with regard to basic game play I do all the events on the client side using local scripts. So the local script knows if I touched the bonus ring and awards the points.

How can I store the points that are awarded from this stuff that happens for the local player in a secure way.

For example let’s say I create a local script function that sends points to the server, what stops an exploiter from triggering that local function.

For example, in the below (hypothetical) script I am using a local script to to initialize a module library myPlayerLib for the current player.

-- In StarterPlayerScripts
local players = game:GetService("Players")
local player = players.LocalPlayer
local myPlayerLib = require(game.ReplicatedStorage.MyPlayerLib).init(player)
myPlayerLib.addPoints(123)

a) Could an exploiter use this to alter someone else’s money? Or are we good because it is local scope?
b) Could an exploiter somehow use it to alter their own money?
c) How could we stop an exploiter being able to access the local variable myPlayerLib and doing stuff with it? Or, can we never stop an exploiter.

Basically what is a secure way to note an event that happened on the client side, and store the points result for that user on the server side?

You can do this:

if game.Players.LocalPlayer then return end;

If LocalPlayer then it return without a return table. (Doesn’t prevent remotevent event)

(Put this on really top code (line number 1))

you cannot “securely” store stats locally, as exploiters can effectively insert their own LocalScript and do everything a normal localscript would be capable of (sometimes more due to their injections) , as for your questions:

I’m assuming the .addPoints() function fires a remote to the server to add the specified points, which on its own is a very very bad practice because you’re effectively allowing an exploiter to give themselves any amount of point they want. a much better way to approach this is to have a remote that fires to the server the point award object the local player touched, have the server checks the magnitude between the player and saidobject (though this does not stops an exploiter from simply teleporting themselves to the object’s position and claim it that way, which you can also somehwat prevent by naming them with a randomized string), then have the server rewards the object’s points. as for your concerns with optimization, this does not have any impacts on the server as simple value addictions are very very resource friendly unless spammed to an extreme level (i.e adding a massive amount every frame)
tl;dr: your system is extremely open to exploiters just do things server-side as the server can handle it

Thanks!

Do you know of a resource or tutorial that teaches how to do this?

Also, maybe I cold use the local event to fire a fires a remote to the serve to test if the user is where they say they are on the server side? And if yes, then on the server side write the points?

you can read more about this on Custom Events and Callbacks | Documentation - Roblox Creator Hub
and What are Sanity Checks? - #3 by Elttob
as for your intended approach, unfortunately it would be entirely redundant to do as the player’s position is replicated to the server, which effectively means when the exploited client “teleports” by changing their CFrame locally, the CFrame change is replicated to the server, which will teleports them on the server. some games counteract this by checking the player’s position everytime it gets changed, and if it moves too unreasonably far at once then the player has teleported (however this isn’t guaranteed to catch an exploiter as laggy players can also teleport themselves on accident in an attempt for the server to catch up to their local position) and bring them back to their previous position or kick them (which is not recommended due to the previous explanation)

1 Like

Final question When I switch to server mode in studio it does not show any player there. Is that just a quirk of studio? In a real server the player is actually there? (That is what is throwing me off and a bit confusing)

server mode basically changes your perspective to the hosted server (which in studio testing is your own computer), you should still be able to see your own character and any other players in multiplayer testing but not players in servers of the actual game itself outside of studio if that’s what you were confused about

1 Like

If client do something to player by changing position. Example,

There is tree and hill. You at hill. Client change your position to tree. Client still at hill, but the client that change position see client at tree, But when server checks, it see you at hill. Client doesn’t replicate anything.

Client cannot see what client doing except self client can see what their doing.

Anything and everything on the client can be changed by an exploiter. A common saying is never trust the client.
Simple answer is to send the goal of the award to the server from the client. On the server assert that player is for example touching the part, then give the points to the player. You should never store points locally or give them points on the client, the only reason you should is for displaying or basic math operations for shop