What's the most optimal way to create a stat system for players?

Currently, I started messing around with a stat system and being using two stats which are “attack” and “strength”. I save the stats to the player’s replicated storage. However, everyone in-game will also hold everyone’s else stats which isn’t really efficient. How could I have it so players only hold their stats and what is the most optimal way to create a stat system?

Here is what my code currently looks like.

local players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStore = game:GetService("DataStoreService")
local statsFolder = ReplicatedStorage:WaitForChild("stats")

local data = {
    ["attack"] = DataStore:GetDataStore("attack"),
    ["strength"] = DataStore:GetDataStore("strength")
}
local default = {
    ["attack"] = 16,
    ["strength"] = 1
}

players.PlayerAdded:connect(function(player)
    local userId = player.userId
    local stats = Instance.new("Folder")
    stats.Name = player.Name

    local attack = Instance.new("IntValue")
    attack.Name = "attack"
     attack.Value = data["attack"]:GetAsync(userId) or default["attack"]

    local strength = Instance.new("IntValue")
    strength.Name = "strength"
    strength.Value = data["strength"]:GetAsync(userId) or default["strength"]

    attack.Parent = stats
    strength.Parent = stats
    stats.Parent = statsFolder
end)

players.PlayerRemoving:connect(function(player)
    local userId = player.userId
    local stats = statsFolder:FindFirstChild(player.Name)
    data["attack"]:SetAsync(userId, stats.attack.Value)
    data["strength"]:SetAsync(userId, stats.strength.Value)
end)

You could make the folder in the player, so the server won’t have to deal with it.

1 Like

Gotcha, so I did this when players join

local stats = Instance.new("Folder")
stats.Name = "stats"
stats.Parent = player

then when a player are removed
local stats = player:FindFirstChild("stats")

Okay, let’s go. So basically, when you think about data saving and all that stuff, you have to keep in mind that you want to make it simple and easy to manage, just so it’ll be better for you if you need to change anything in the future.
What I recommend is making a module in which you’ll have a table with all the player stats, and save it using a datastore, you don’t need to make multiple. If you make multiple datastores for a player, it might take a while to save/load and it may even fail due to various http requests. Have a module containing a table and put all the stats inside it, then upon joining the player’s data will be loaded and put in a table inside the module, and you can implement functions to change the data then save upon leaving and even an auto save function! This way, things will be better for you and you won’t have to worry about data handling.

9 Likes

Not super familiar with modules, but definitely sounds like the way to go! Going to have to do more studying, but I do have one question for you.

When you say not needing multiple data stores. For example in my code I have this which would be multiple datastores.

local data = {
["attack"] = DataStore:GetDataStore("attack"),
["strength"] = DataStore:GetDataStore("strength")
}

In the module I would instead have a table that loops through and then does a datastore I’m assuming? Correct me if I’m wrong.

1 Like

Datastore issues aside, I think typically a lot of games will use the ‘leaderstats’ folder in the Player to store the stats which will automatically show in the built in leaderboard in the roblox client (if you wish to use the built-in leaderboard)
this thing:
image