Data saving values or table?

Hi, I have a stats folder that is parented under a player and the folder contains values like level, I have like over 10 values and I’m wondering if I should just keep going this way,

How I save is that I loop through the stats then save the index which is Name of stats and the value of the stats and I save that in a table for the data store to save.

However I’m wondering if I should convert to just making it strictly table based meaning no int values but just e.g.
[“Level”] = 0

Issue with the above thing is that how can I inform client a level up happened? Because with int values I can simply do with by using .changed and since stats value is under player it makes it easy accessible for gui aspect of game it can be as simple as screengui.coins.text = player.stats.coins.value, where as with table based how can I inform the client of data of player with no hassle?

Using value objects in the player is exploitable. It’s still possible, but I personally moved to using tables. A module that simplifies this for the developer is ProfileService. It allows you to create functions for manipulating your data ex. GiveCash, and it saves the data as it changes.

In what case would it be exploitable? because I handle the buying stuff server side and I doubt i’d put a remote out there for players to use to fire to give themselves cash

2 Likes

This is not exploitable. Client changes to instances not given network ownership do not replicate.

OP, there is no singular correct answer. If you’d like to cache player data about value objects on the server to avoid pointless Get requests up until you save, I see nothing wrong with this (provided you know what you’re doing).

Our games cache using tables. Data updates push to the client who received an update, and update their client-side data table. This way we can check data on client & kick on server for malformed Remote requests.

It’s also worth mentioning that, if you really wanted to, you can write .Changed for table value types by using metatables and a proxy table (for a cached client-side table though, you might as well just update your values when you receive the request).

2 Likes

That’s why you do sanity checks, checking if the value is correct / is a system thing.
It isn’t exploitable, something from the client that is changed for example name & userid will not change through the server & which exploiters purposely find remotes (to fire) to give them, something like cash.

For example, giving cash remote event for finishing NPC.

local event = game.Replicatedstorage.Event

event.OnServerEvent:Connect(function(player)
      local sanityCheck = player.CanBeGivenMoney.Value
       if sanityCheck then
             player.Leaderstats.Cash.Value = player.Leaderstats.Cash.Value +  25
      else
            player:Kick("trying to fire a event that you cannot.")
      end
end)

This is a simple way of a workaround / way around it.