What's the best way to save local stats?

For a game I’m working on, many of the stats I want to save are local, and I want to figure out the best way to go about saving it.

I know passing all the values I want through a RemoteFunction to a server script is one option, but if I do this, how often should I save auto-save? Or how would I have it save when the player left (if the remote is triggered from the client?)

Or is there a better way to do it?

3 Likes

Stats shouldn’t be local, anything that is local can be modified entirely so your server needs to have full control over stats.

As for auto saving, you need to ask yourself how much time can pass before lost progress matters. For many games, losing a few minutes worth of stat changes isn’t going to be significant, but certainly not for all games.

See Players.PlayerRemoving. There’s no need for a remote event when a player leaves.

4 Likes

What kind of local stats are you saving and why. Anything on the client can be modified so I’m curious as to why you would want to save anything locally.

Although to answer your question you should use a RemoteEvent/RemoteFunction to get the data to the server.

From there you know what to do. Auto-save either when the player progresses significantly (like they reach +10 levels or something) or find out how fast the player is to progress. (5 Minutes is usually good although you may even be able to let the player set a specific time range to better suit their play style).

As for when the player leaves, call the Players.PlayerRemoving event on the client and send your data.

Again - I have no idea why you are saving values from the client. It breaks rule number 1:

Never Trust The Client

1 Like

Just like spencer said Never trust the client, You can do a player removing function on the server to save all the player’s data when they leave and also, Use the “game:BindToClose:Connect(function()” so that you can save the data safely when the game gets shutdown.

1 Like

I can see what you’re trying to do - you should provide a use case so others can assist you. What you’re probably trying to do is save something like settings, right? If you want to save stats locally, you should pass such stats to the server but ensure that the stats are completely separated from non-local stats and that you’re holding the client to heavy restrictions.

I know there’s all this “don’t trust the client” grumble grumble stuff above me, but in the case of local stats you’re going to have to get creative. So long as none of your local stats affect the game and it doesn’t even matter what an exploiter sets, then really just go right ahead and do something.

The workflow process I would suggest:

  • The client invokes a RemoteFunction, so it can receive returns from the server. This is a request made from the client to push new values to the server.
  • The server receives the request and the data sent. It does a heavy process of verification: checking the budget, the last time a request was sent, performing validation so it isn’t receiving bad requests, so on. Make sure the security is like that of an airport.
  • The server, once validation is complete, accepts or rejects this request. If it’s rejected, send something back to the client to inform it of the decision. If it’s accepted, store the received data in a scope or key completely separate to normal data.
  • There you are.

If your use case isn’t something like settings and the values are critical to gameplay, then don’t do it. You’re making an unnecessary risk and your exploiters are going to absolutely love that opportunity. You will also have to include a manual save option, because once a player disconnects you can’t fetch anything else. Only delve into locally-saved stats if they only affect player experience, not if they have value to gameplay.

1 Like

Ohhhhh I didn’t think of settings. But why would you save those periodically as opposed to when they are changed?

It’s much more efficient to save the settings after they are altered rather than periodically

Settings are the one thing you don’t want to save periodically. I wouldn’t even save on alteration because that’s going to be as exhaustive but slightly less than periodic saving. You should always wait for clients to make the actual request so that the server can confirm. That’s through the use of a save button.

On another note, personally, I’d like to look into a Feature Request for client game caching for things like this - editing settings.

https://www.robloxdev.com/articles/Data-store

Simple Datastore Handler Tutorial

Details on DataStoreService for Advanced Developers

How do I write this DataStore script in the best way?

Methods for Handling DataStore Request

Datastore Organization

Should work :wink:

1 Like

I was making customization system and I was saving my character appearance locally. What did I do? I made an Event Folder and placed a Remote Event inside of it. Using save button I made I was just saving my data, so once I click on that button, I will fire that event to the server and get it in Data Store script using OnServerEvent function.

I realized the risks of putting trust on the client. I am well aware of how easy it is for people to cheat if you trust the client for that kind of thing. However, it is a single player game with no leaderboard, so if they cheat, they are just ruining the experience for themselves.

To be honest, it’s more of a proof-of-concept, but thanks for your replies.

1 Like